[PATCH] vxlan: avoid double unlikely() notation when using IS_ERR()
The definition of IS_ERR() already applies the unlikely() notation when checking the error status of the passed pointer. For this reason there is no need to have the same notation outside of IS_ERR() itself. Clean up code by removing redundant notation. Signed-off-by: Antonio Quartulli --- drivers/net/vxlan.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c index e1e44d68ac4b..a8ad710629e6 100644 --- a/drivers/net/vxlan.c +++ b/drivers/net/vxlan.c @@ -2477,7 +2477,7 @@ static struct dst_entry *vxlan6_get_route(struct vxlan_dev *vxlan, ndst = ipv6_stub->ipv6_dst_lookup_flow(vxlan->net, sock6->sock->sk, &fl6, NULL); - if (unlikely(IS_ERR(ndst))) { + if (IS_ERR(ndst)) { netdev_dbg(dev, "no route to %pI6\n", daddr); return ERR_PTR(-ENETUNREACH); } -- 2.29.2
[PATCH] wireguard: avoid double unlikely() notation when using IS_ERR()
The definition of IS_ERR() already applies the unlikely() notation when checking the error status of the passed pointer. For this reason there is no need to have the same notation outside of IS_ERR() itself. Clean up code by removing redundant notation. Signed-off-by: Antonio Quartulli --- drivers/net/wireguard/device.c | 2 +- drivers/net/wireguard/socket.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireguard/device.c b/drivers/net/wireguard/device.c index a3ed49cd95c3..cd51a2afa28e 100644 --- a/drivers/net/wireguard/device.c +++ b/drivers/net/wireguard/device.c @@ -157,7 +157,7 @@ static netdev_tx_t wg_xmit(struct sk_buff *skb, struct net_device *dev) } else { struct sk_buff *segs = skb_gso_segment(skb, 0); - if (unlikely(IS_ERR(segs))) { + if (IS_ERR(segs)) { ret = PTR_ERR(segs); goto err_peer; } diff --git a/drivers/net/wireguard/socket.c b/drivers/net/wireguard/socket.c index c33e2c81635f..e9c35130846c 100644 --- a/drivers/net/wireguard/socket.c +++ b/drivers/net/wireguard/socket.c @@ -71,7 +71,7 @@ static int send4(struct wg_device *wg, struct sk_buff *skb, ip_rt_put(rt); rt = ip_route_output_flow(sock_net(sock), &fl, sock); } - if (unlikely(IS_ERR(rt))) { + if (IS_ERR(rt)) { ret = PTR_ERR(rt); net_dbg_ratelimited("%s: No route to %pISpfsc, error %d\n", wg->dev->name, &endpoint->addr, ret); @@ -138,7 +138,7 @@ static int send6(struct wg_device *wg, struct sk_buff *skb, } dst = ipv6_stub->ipv6_dst_lookup_flow(sock_net(sock), sock, &fl, NULL); - if (unlikely(IS_ERR(dst))) { + if (IS_ERR(dst)) { ret = PTR_ERR(dst); net_dbg_ratelimited("%s: No route to %pISpfsc, error %d\n", wg->dev->name, &endpoint->addr, ret); -- 2.29.2
[PATCH] can: avoid double unlikely() notation when using IS_ERR()
The definition of IS_ERR() already applies the unlikely() notation when checking the error status of the passed pointer. For this reason there is no need to have the same notation outside of IS_ERR() itself. Clean up code by removing redundant notation. Signed-off-by: Antonio Quartulli --- drivers/net/can/rx-offload.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/can/rx-offload.c b/drivers/net/can/rx-offload.c index 450c5cfcb3fc..3c1912c0430b 100644 --- a/drivers/net/can/rx-offload.c +++ b/drivers/net/can/rx-offload.c @@ -157,7 +157,7 @@ can_rx_offload_offload_one(struct can_rx_offload *offload, unsigned int n) /* There was a problem reading the mailbox, propagate * error value. */ - if (unlikely(IS_ERR(skb))) { + if (IS_ERR(skb)) { offload->dev->stats.rx_dropped++; offload->dev->stats.rx_fifo_errors++; -- 2.29.2
Re: [PATCH cryptodev] crypto: lib/chacha20poly1305 - allow users to specify 96bit nonce
Hi, On 17/11/2020 10:52, Ard Biesheuvel wrote: > On Tue, 17 Nov 2020 at 10:47, Antonio Quartulli wrote: >> >> Hi, >> >> >> On 17/11/2020 09:31, Ard Biesheuvel wrote: >>> If you are going back to the drawing board with in-kernel acceleration >>> for OpenVPN, I strongly suggest to: >>> a) either stick to one implementation, and use the library interface, >>> or use dynamic dispatch using the crypto API AEAD abstraction, which >>> already implements 96-bit nonces for ChaCha20Poly1305, >> >> What we are implementing is a simple Data Channel Offload, which is >> expected to be compatible with the current userspace implementation. >> Therefore we don't want to change how encryption is performed. >> >> Using the crypto API AEAD abstraction will be my next move at this point. >> > > Aren't you already using that for gcm(aes) ? Yes, correct. That's why I had no real objection to using it :-) At first I was confused and I thought this new library interface was "the preferred way" for using chacha20poly1305, therefore I went down this path. > >> I just find it a bit strange that an API of a well defined crypto schema >> is implemented in a way that accommodates only some of its use cases. >> > > You mean the 64-bit nonce used by the library version of > ChaCha20Poly1305? I agree that this is a bit unusual, but a library > interface doesn't seem like the right abstraction for this in the > first place, so I guess it is irrelevant. Alright. > >> >> But I guess it's accepted that we will have to live with two APIs for a bit. >> >> >>> b) consider using Aegis128 instead of AES-GCM or ChaChaPoly - it is >>> one of the winners of the CAESAR competition, and on hardware that >>> supports AES instructions, it is extremely efficient, and not >>> encumbered by the same issues that make AES-GCM tricky to use. >>> >>> We might implement a library interface for Aegis128 if that is preferable. >> >> Thanks for the pointer! >> I guess we will consider supporting Aegis128 once it gets standardized >> (AFAIK it is not yet). >> > > It is. The CAESAR competition is over, and produced a suite of > recommended algorithms, one of which is Aegis128 for the high > performance use case. (Note that other variants of Aegis did not make > it into the final recommendation) oops, I was not up-to-date. Thanks again! We'll definitely look into this soon. Best Regards, -- Antonio Quartulli OpenVPN Inc.
Re: [PATCH cryptodev] crypto: lib/chacha20poly1305 - allow users to specify 96bit nonce
Hi, On 17/11/2020 09:31, Ard Biesheuvel wrote: > If you are going back to the drawing board with in-kernel acceleration > for OpenVPN, I strongly suggest to: > a) either stick to one implementation, and use the library interface, > or use dynamic dispatch using the crypto API AEAD abstraction, which > already implements 96-bit nonces for ChaCha20Poly1305, What we are implementing is a simple Data Channel Offload, which is expected to be compatible with the current userspace implementation. Therefore we don't want to change how encryption is performed. Using the crypto API AEAD abstraction will be my next move at this point. I just find it a bit strange that an API of a well defined crypto schema is implemented in a way that accommodates only some of its use cases. But I guess it's accepted that we will have to live with two APIs for a bit. > b) consider using Aegis128 instead of AES-GCM or ChaChaPoly - it is > one of the winners of the CAESAR competition, and on hardware that > supports AES instructions, it is extremely efficient, and not > encumbered by the same issues that make AES-GCM tricky to use. > > We might implement a library interface for Aegis128 if that is preferable. Thanks for the pointer! I guess we will consider supporting Aegis128 once it gets standardized (AFAIK it is not yet). Best Regards, -- Antonio Quartulli
Re: [PATCH cryptodev] crypto: lib/chacha20poly1305 - allow users to specify 96bit nonce
Hello, On 17/11/2020 09:30, Jason A. Donenfeld wrote: > Nack. > > This API is meant to take simple integers, so that programmers can use > atomic64_t with it and have safe nonces. I'm also interested in > preserving the API's ability to safely encrypt more than 4 gigs of > data at once. Passing a buffer also encourages people to use > randomized nonces, which isn't really safe. Finally, there are no > in-tree users of 96bit nonces for this interface. If you're after a > cornucopia of compatibility primitives, the ipsec stuff might be more > to your fitting. Or, add a new simple function/api. But adding > complexity to users of the existing one and confusing future users of > it is a non-starter. It's supposed to be deliberately non-awful to > use. > Thanks for explaining the ratio behind this API. At first I thought this API wanted to take over the existing one, hence my attempt of making it more generic and re-use it. But I understand now this was not the goal. I will stick to the classic crypto API then. Best Regards, p.s. I am curious about any use case you may have in mind for encrypting more than 4GB in one go, as there are no users doing that right now. -- Antonio Quartulli
[PATCH cryptodev] crypto: lib/chacha20poly1305 - allow users to specify 96bit nonce
From: Antonio Quartulli The current interface limits the nonce 64bit, however, new users may want to specify a 96bit nonce, as dictated by the AEAD_CHACHA20_POLY1305 construction in RFC7539 Section 2.8. This patch changes the interface from accepting the nonce as single u64 variable to an array of 12 bytes. Since ChaCha still expects an IV of 16 bytes, the nonce is transferred to a termporary 16byte long buffer, where the initial 8 bytes are set to 0 (ChaCha block counter). At the end of the procedure, the IV is explicitly overwritten with zeros. The only two in-tree users of this interface are: - WireGuard[tm] - security/keys/big_key.c Both have been modified accordingly to accommodate the new API. The chacha20poly1305-selftest has also been updated by getting rid of the _bignonce() wrapper and by prepending every 8byte long nonce with 4 0-octects.. Cc: "Jason A. Donenfeld" Cc: Herbert Xu Cc: David Howells Cc: Jarkko Sakkinen Cc: Jakub Kicinski Signed-off-by: Antonio Quartulli --- Note: I am not 100% sure that the WireGuard[tm] adaptation to the new API is optimal. But after several attempts, this is the simplest I could come up with. Feedback is welcome! *** For the curious reader: the "other user" I am concerned about is ovpn-dco. ovpn-dco is the implementation of the OpenVPN data channel offload in kernelspace. It is currently under heavy development and the source code is available online at: g...@gitlab.com:openvpn/ovpn-dco.git Next to AES-GCM it will also support ChaCha20Poly1305 and therefore we decided to re-use this relatively new API. *** drivers/net/wireguard/noise.c | 5 +- drivers/net/wireguard/receive.c| 18 +- drivers/net/wireguard/send.c | 19 +- include/crypto/chacha20poly1305.h | 10 +- lib/crypto/chacha20poly1305-selftest.c | 309 ++--- lib/crypto/chacha20poly1305.c | 44 ++-- security/keys/big_key.c| 6 +- 7 files changed, 242 insertions(+), 169 deletions(-) diff --git a/drivers/net/wireguard/noise.c b/drivers/net/wireguard/noise.c index c0cfd9b36c0b..6f773807eba0 100644 --- a/drivers/net/wireguard/noise.c +++ b/drivers/net/wireguard/noise.c @@ -433,7 +433,7 @@ static void message_encrypt(u8 *dst_ciphertext, const u8 *src_plaintext, { chacha20poly1305_encrypt(dst_ciphertext, src_plaintext, src_len, hash, NOISE_HASH_LEN, -0 /* Always zero for Noise_IK */, key); +page_address(ZERO_PAGE(0)) /* Always zero for Noise_IK */, key); mix_hash(hash, dst_ciphertext, noise_encrypted_len(src_len)); } @@ -443,7 +443,8 @@ static bool message_decrypt(u8 *dst_plaintext, const u8 *src_ciphertext, { if (!chacha20poly1305_decrypt(dst_plaintext, src_ciphertext, src_len, hash, NOISE_HASH_LEN, - 0 /* Always zero for Noise_IK */, key)) + page_address(ZERO_PAGE(0)) /* Always zero for Noise_IK */, + key)) return false; mix_hash(hash, src_ciphertext, src_len); return true; diff --git a/drivers/net/wireguard/receive.c b/drivers/net/wireguard/receive.c index 2c9551ea6dc7..ab736cc34e93 100644 --- a/drivers/net/wireguard/receive.c +++ b/drivers/net/wireguard/receive.c @@ -248,9 +248,11 @@ static void keep_key_fresh(struct wg_peer *peer) static bool decrypt_packet(struct sk_buff *skb, struct noise_keypair *keypair) { struct scatterlist sg[MAX_SKB_FRAGS + 8]; + u8 nonce[CHACHA20POLY1305_NONCE_SIZE]; struct sk_buff *trailer; unsigned int offset; int num_frags; + bool ret; if (unlikely(!keypair)) return false; @@ -265,6 +267,14 @@ static bool decrypt_packet(struct sk_buff *skb, struct noise_keypair *keypair) PACKET_CB(skb)->nonce = le64_to_cpu(((struct message_data *)skb->data)->counter); + /* the nonce is 96-bit long: +* - 00..31: zero +* - 31..95: packet counter in LE +*/ + memset(nonce, 0, 4); + memcpy(nonce + 4, &((struct message_data *)skb->data)->counter, + sizeof(((struct message_data *)skb->data)->counter)); + /* We ensure that the network header is part of the packet before we * call skb_cow_data, so that there's no chance that data is removed * from the skb, so that later we can extract the original endpoint. @@ -281,9 +291,11 @@ static bool decrypt_packet(struct sk_buff *skb, struct noise_keypair *keypair) if (skb_to_sgvec(skb, sg, 0, skb->len) <= 0) return false; - if (!chacha20poly1305_decrypt_sg_inplace(sg, skb->len, NULL, 0, -PACKET_CB(skb)->nonce, -
Re: [PATCH] net/sch_generic.h: use sizeof_member() and get rid of unused variable
On 20/05/2020 20:17, David Miller wrote: > From: Antonio Quartulli > Date: Wed, 20 May 2020 10:39:33 +0200 > >> I don't think it's BUILD_BUG_ON()'s fault, because qcb->data is passed >> to sizeof() first. >> >> My best guess is that gcc is somewhat optimizing the sizeof(gcb->data) >> and thus leaving the gcb variable unused. > > If you remove the argument from the function but leave the BUILD_BUG_ON() > calls the same, the compilation will fail. > > Any such optimization is therefore unreasonable. > > The variable is used otherwise compilation would not fail when you > remove it right? You're correct. I guess this should be reported to gcc then. Regards, -- Antonio Quartulli
Re: [PATCH] net/sch_generic.h: use sizeof_member() and get rid of unused variable
Hi David, On 20/05/2020 00:40, David Miller wrote: > From: Antonio Quartulli > Date: Tue, 19 May 2020 11:13:33 +0200 > >> Compiling with -Wunused triggers the following warning: >> >> ./include/net/sch_generic.h: In function ‘qdisc_cb_private_validate’: >> ./include/net/sch_generic.h:464:23: warning: unused variable ‘qcb’ >> [-Wunused-variable] >> 464 | struct qdisc_skb_cb *qcb; >> | ^~~ >> >> as the qcb variable is only used to compute the sizeof one of its members. > > It's referenced in the code, therefore it is not "unused". True. > > If in some configuration BUILD_BUG_ON() does not reference it's arguments, > that's the bug that needs to be fixed. > I don't think it's BUILD_BUG_ON()'s fault, because qcb->data is passed to sizeof() first. My best guess is that gcc is somewhat optimizing the sizeof(gcb->data) and thus leaving the gcb variable unused. This said, I think it's better for the code style (and for the compiler) if we used sizeof_member(). Should I resend the patch with a commit message that does not mention the "unused" warning? Thanks a lot. Best Regards, -- Antonio Quartulli
[PATCH] net/sch_generic.h: use sizeof_member() and get rid of unused variable
Compiling with -Wunused triggers the following warning: ./include/net/sch_generic.h: In function ‘qdisc_cb_private_validate’: ./include/net/sch_generic.h:464:23: warning: unused variable ‘qcb’ [-Wunused-variable] 464 | struct qdisc_skb_cb *qcb; | ^~~ as the qcb variable is only used to compute the sizeof one of its members. Get rid of the warning by using the provided sizeof_member() macro and avoid having a variable at all. At the same time use sizeof_member() also for computing the sizeof skb->cb, thus avoiding ‘qdisc_cb_private_validate’ to have an skb argument at all. Cc: Toke Høiland-Jørgensen Cc: Jamal Hadi Salim Cc: Cong Wang Cc: Jiri Pirko Cc: Stephen Hemminger Signed-off-by: Antonio Quartulli --- Affected code has been compile-tested on x86_64 include/net/codel_qdisc.h | 2 +- include/net/pie.h | 2 +- include/net/sch_generic.h | 9 - net/sched/sch_cake.c | 2 +- net/sched/sch_choke.c | 2 +- net/sched/sch_fq.c| 2 +- net/sched/sch_netem.c | 2 +- net/sched/sch_sfb.c | 2 +- 8 files changed, 11 insertions(+), 12 deletions(-) diff --git a/include/net/codel_qdisc.h b/include/net/codel_qdisc.h index 098630f83a55..c59d17de4ef3 100644 --- a/include/net/codel_qdisc.h +++ b/include/net/codel_qdisc.h @@ -57,7 +57,7 @@ struct codel_skb_cb { static struct codel_skb_cb *get_codel_cb(const struct sk_buff *skb) { - qdisc_cb_private_validate(skb, sizeof(struct codel_skb_cb)); + qdisc_cb_private_validate(sizeof(struct codel_skb_cb)); return (struct codel_skb_cb *)qdisc_skb_cb(skb)->data; } diff --git a/include/net/pie.h b/include/net/pie.h index 3fe2361e03b4..c15fe3032ad0 100644 --- a/include/net/pie.h +++ b/include/net/pie.h @@ -109,7 +109,7 @@ static inline void pie_vars_init(struct pie_vars *vars) static inline struct pie_skb_cb *get_pie_cb(const struct sk_buff *skb) { - qdisc_cb_private_validate(skb, sizeof(struct pie_skb_cb)); + qdisc_cb_private_validate(sizeof(struct pie_skb_cb)); return (struct pie_skb_cb *)qdisc_skb_cb(skb)->data; } diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h index c510b03b9751..8e1f7a0d7572 100644 --- a/include/net/sch_generic.h +++ b/include/net/sch_generic.h @@ -459,12 +459,11 @@ static inline bool lockdep_tcf_proto_is_locked(struct tcf_proto *tp) #define tcf_proto_dereference(p, tp) \ rcu_dereference_protected(p, lockdep_tcf_proto_is_locked(tp)) -static inline void qdisc_cb_private_validate(const struct sk_buff *skb, int sz) +static inline void qdisc_cb_private_validate(int sz) { - struct qdisc_skb_cb *qcb; - - BUILD_BUG_ON(sizeof(skb->cb) < offsetof(struct qdisc_skb_cb, data) + sz); - BUILD_BUG_ON(sizeof(qcb->data) < sz); + BUILD_BUG_ON(sizeof_field(struct sk_buff, cb) < +offsetof(struct qdisc_skb_cb, data) + sz); + BUILD_BUG_ON(sizeof_field(struct qdisc_skb_cb, data) < sz); } static inline int qdisc_qlen_cpu(const struct Qdisc *q) diff --git a/net/sched/sch_cake.c b/net/sched/sch_cake.c index 1496e87cd07b..2800551b7465 100644 --- a/net/sched/sch_cake.c +++ b/net/sched/sch_cake.c @@ -281,7 +281,7 @@ static u64 us_to_ns(u64 us) static struct cobalt_skb_cb *get_cobalt_cb(const struct sk_buff *skb) { - qdisc_cb_private_validate(skb, sizeof(struct cobalt_skb_cb)); + qdisc_cb_private_validate(sizeof(struct cobalt_skb_cb)); return (struct cobalt_skb_cb *)qdisc_skb_cb(skb)->data; } diff --git a/net/sched/sch_choke.c b/net/sched/sch_choke.c index bd618b00d319..6badd324df43 100644 --- a/net/sched/sch_choke.c +++ b/net/sched/sch_choke.c @@ -137,7 +137,7 @@ struct choke_skb_cb { static inline struct choke_skb_cb *choke_skb_cb(const struct sk_buff *skb) { - qdisc_cb_private_validate(skb, sizeof(struct choke_skb_cb)); + qdisc_cb_private_validate(sizeof(struct choke_skb_cb)); return (struct choke_skb_cb *)qdisc_skb_cb(skb)->data; } diff --git a/net/sched/sch_fq.c b/net/sched/sch_fq.c index 8f06a808c59a..0c2497509a3d 100644 --- a/net/sched/sch_fq.c +++ b/net/sched/sch_fq.c @@ -56,7 +56,7 @@ struct fq_skb_cb { static inline struct fq_skb_cb *fq_skb_cb(struct sk_buff *skb) { - qdisc_cb_private_validate(skb, sizeof(struct fq_skb_cb)); + qdisc_cb_private_validate(sizeof(struct fq_skb_cb)); return (struct fq_skb_cb *)qdisc_skb_cb(skb)->data; } diff --git a/net/sched/sch_netem.c b/net/sched/sch_netem.c index 84f82771cdf5..2b930d928c5c 100644 --- a/net/sched/sch_netem.c +++ b/net/sched/sch_netem.c @@ -161,7 +161,7 @@ struct netem_skb_cb { static inline struct netem_skb_cb *netem_skb_cb(struct sk_buff *skb) { /* we assume we can use skb next/prev/tstamp as storage for rb_node */ - qdisc_cb_private_validate(skb, sizeof(struct netem_skb_cb)); + qdisc_cb_private_validate(sizeof(struct netem_skb_cb));
Re: [iproute2 2/2] ss: fix NULL pointer access when parsing unix sockets with oldformat
Hi, On 07/01/18 03:28, Stefano Brivio wrote: > On Sun, 7 Jan 2018 02:31:50 +0800 > Antonio Quartulli wrote: > >> When parsing and printing the unix sockets in unix_show(), >> if the oldformat is detected, the peer_name member of the sockstat >> object is left uninitialized (NULL). > > Luckily, it is initialized. I'd rather say: > > [...] > object is not set (NULL). ops, you are right! "is not set" makes more sense. > >> For this reason, if a filter has been specified on the command line, >> a strcmp() will crash when trying to access it. >> >> Avoid crash by checking that peer_name is not NULL before >> passing it to strcmp(). >> >> Cc: Stefano Brivio >> Cc: Stephen Hemminger >> Signed-off-by: Antonio Quartulli > > Fixes: 2d0e538f3e1c ("ss: Drop list traversal from unix_stats_print()") > >> [...] >> >> diff --git a/misc/ss.c b/misc/ss.c >> index b35859dc..29a25070 100644 >> --- a/misc/ss.c >> +++ b/misc/ss.c >> @@ -3711,7 +3711,10 @@ static int unix_show(struct filter *f) >> }; >> >> memcpy(st.local.data, &u->name, sizeof(u->name)); >> -if (strcmp(u->peer_name, "*")) >> +/* when parsing the old format rport is set to 0 and >> + * therefore peer_name remains NULL >> + */ > > Maybe this comment is a bit redundant, but I don't have a strong > preference either. > I thought explaining "why" it could be NULL would help the casual reader understand why we do check it. But now that we have the check, I think it's quick to understand why we need it. I'd leave to whoever is going to merge the match to decide to keep or not the comment. >> +if (u->peer_name && strcmp(u->peer_name, "*")) >> memcpy(st.remote.data, &u->peer_name, >> sizeof(u->peer_name)); >> if (run_ssfilter(f->f, &st) == 0) { > > FWIW: > Reviewed-by: Stefano Brivio > Thanks a lot, Stefano! Should I send v2 with the commit message changed? Or can we leave this to who will merge the change? Regards, -- Antonio Quartulli signature.asc Description: OpenPGP digital signature
[iproute2 2/2] ss: fix NULL pointer access when parsing unix sockets with oldformat
When parsing and printing the unix sockets in unix_show(), if the oldformat is detected, the peer_name member of the sockstat object is left uninitialized (NULL). For this reason, if a filter has been specified on the command line, a strcmp() will crash when trying to access it. Avoid crash by checking that peer_name is not NULL before passing it to strcmp(). Cc: Stefano Brivio Cc: Stephen Hemminger Signed-off-by: Antonio Quartulli --- To crash ss, simply execute the following on a system using the old socket format: ss -x dst 192.168.1.1 or ss dst 192.168.1.1 (crash reproduced on linux-4.12.12) misc/ss.c | 5 - 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/misc/ss.c b/misc/ss.c index b35859dc..29a25070 100644 --- a/misc/ss.c +++ b/misc/ss.c @@ -3711,7 +3711,10 @@ static int unix_show(struct filter *f) }; memcpy(st.local.data, &u->name, sizeof(u->name)); - if (strcmp(u->peer_name, "*")) + /* when parsing the old format rport is set to 0 and +* therefore peer_name remains NULL +*/ + if (u->peer_name && strcmp(u->peer_name, "*")) memcpy(st.remote.data, &u->peer_name, sizeof(u->peer_name)); if (run_ssfilter(f->f, &st) == 0) { -- 2.15.1
[iproute2 1/2] ss: fix crash when skipping disabled header field
When the first header field is disabled (i.e. when passing the -t option), field_flush() is invoked with the `buffer` global variable still zero'd. However, in field_flush() we try to access buffer.cur->len during variables initialization, thus leading to a SIGSEGV. It's interesting to note that this bug appears only when the code is compiled with -O0, because the compiler is smart enough to immediately jump to the return statement if optimizations are enabled and skip the faulty instruction. Cc: Stefano Brivio Cc: Stephen Hemminger Signed-off-by: Antonio Quartulli --- misc/ss.c | 7 +-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/misc/ss.c b/misc/ss.c index 1abf43d0..b35859dc 100644 --- a/misc/ss.c +++ b/misc/ss.c @@ -1018,12 +1018,15 @@ static void print_right_spacing(struct column *f, int printed) /* Done with field: update buffer pointer, start new token after current one */ static void field_flush(struct column *f) { - struct buf_chunk *chunk = buffer.tail; - unsigned int pad = buffer.cur->len % 2; + struct buf_chunk *chunk; + unsigned int pad; if (f->disabled) return; + chunk = buffer.tail; + pad = buffer.cur->len % 2; + if (buffer.cur->len > f->max_len) f->max_len = buffer.cur->len; -- 2.15.1
[PATCH v4] skbedit: allow the user to specify bitmask for mark
The user may want to use only some bits of the skb mark in his skbedit rules because the remaining part might be used by something else. Introduce the "mask" parameter to the skbedit actor in order to implement such functionality. When the mask is specified, only those bits selected by the latter are altered really changed by the actor, while the rest is left untouched. Signed-off-by: Antonio Quartulli Signed-off-by: Jamal Hadi Salim --- This patch has been sleeping for a while although it was basically ready for being merged. I hope it can still be merged. Checkpatch is now complaining about this: CHECK: Comparison to NULL could be written "tb[TCA_SKBEDIT_MASK]" #112: FILE: net/sched/act_skbedit.c:114: + if (tb[TCA_SKBEDIT_MASK] != NULL) { However the surrounding code does not use this codestyle. Please, let me know if I should rearrange this line. Thanks! Changes from v3: - rebase on top of net-next - fix syntax error in if statement Changes from v2: - remove useless comments - use nla_put_u32() and fix typ0 Changes from v1: - use '&=' tcf_skbedit() to clean the mark - extend tcf_skbedit_dump() in order to send the mask as well include/net/tc_act/tc_skbedit.h| 1 + include/uapi/linux/tc_act/tc_skbedit.h | 2 ++ net/sched/act_skbedit.c| 21 ++--- 3 files changed, 21 insertions(+), 3 deletions(-) diff --git a/include/net/tc_act/tc_skbedit.h b/include/net/tc_act/tc_skbedit.h index 5767e9dbcf92..19cd3d345804 100644 --- a/include/net/tc_act/tc_skbedit.h +++ b/include/net/tc_act/tc_skbedit.h @@ -27,6 +27,7 @@ struct tcf_skbedit { u32 flags; u32 priority; u32 mark; + u32 mask; u16 queue_mapping; u16 ptype; }; diff --git a/include/uapi/linux/tc_act/tc_skbedit.h b/include/uapi/linux/tc_act/tc_skbedit.h index a4d00c608d8f..2884425738ce 100644 --- a/include/uapi/linux/tc_act/tc_skbedit.h +++ b/include/uapi/linux/tc_act/tc_skbedit.h @@ -28,6 +28,7 @@ #define SKBEDIT_F_QUEUE_MAPPING0x2 #define SKBEDIT_F_MARK 0x4 #define SKBEDIT_F_PTYPE0x8 +#define SKBEDIT_F_MASK 0x10 struct tc_skbedit { tc_gen; @@ -42,6 +43,7 @@ enum { TCA_SKBEDIT_MARK, TCA_SKBEDIT_PAD, TCA_SKBEDIT_PTYPE, + TCA_SKBEDIT_MASK, __TCA_SKBEDIT_MAX }; #define TCA_SKBEDIT_MAX (__TCA_SKBEDIT_MAX - 1) diff --git a/net/sched/act_skbedit.c b/net/sched/act_skbedit.c index a133dcb82132..024f3a3afeff 100644 --- a/net/sched/act_skbedit.c +++ b/net/sched/act_skbedit.c @@ -46,8 +46,10 @@ static int tcf_skbedit(struct sk_buff *skb, const struct tc_action *a, if (d->flags & SKBEDIT_F_QUEUE_MAPPING && skb->dev->real_num_tx_queues > d->queue_mapping) skb_set_queue_mapping(skb, d->queue_mapping); - if (d->flags & SKBEDIT_F_MARK) - skb->mark = d->mark; + if (d->flags & SKBEDIT_F_MARK) { + skb->mark &= ~d->mask; + skb->mark |= d->mark & d->mask; + } if (d->flags & SKBEDIT_F_PTYPE) skb->pkt_type = d->ptype; @@ -61,6 +63,7 @@ static const struct nla_policy skbedit_policy[TCA_SKBEDIT_MAX + 1] = { [TCA_SKBEDIT_QUEUE_MAPPING] = { .len = sizeof(u16) }, [TCA_SKBEDIT_MARK] = { .len = sizeof(u32) }, [TCA_SKBEDIT_PTYPE] = { .len = sizeof(u16) }, + [TCA_SKBEDIT_MASK] = { .len = sizeof(u32) }, }; static int tcf_skbedit_init(struct net *net, struct nlattr *nla, @@ -71,7 +74,7 @@ static int tcf_skbedit_init(struct net *net, struct nlattr *nla, struct nlattr *tb[TCA_SKBEDIT_MAX + 1]; struct tc_skbedit *parm; struct tcf_skbedit *d; - u32 flags = 0, *priority = NULL, *mark = NULL; + u32 flags = 0, *priority = NULL, *mark = NULL, *mask = NULL; u16 *queue_mapping = NULL, *ptype = NULL; bool exists = false; int ret = 0, err; @@ -108,6 +111,11 @@ static int tcf_skbedit_init(struct net *net, struct nlattr *nla, mark = nla_data(tb[TCA_SKBEDIT_MARK]); } + if (tb[TCA_SKBEDIT_MASK] != NULL) { + flags |= SKBEDIT_F_MASK; + mask = nla_data(tb[TCA_SKBEDIT_MASK]); + } + parm = nla_data(tb[TCA_SKBEDIT_PARMS]); exists = tcf_hash_check(tn, parm->index, a, bind); @@ -145,6 +153,10 @@ static int tcf_skbedit_init(struct net *net, struct nlattr *nla, d->mark = *mark; if (flags & SKBEDIT_F_PTYPE) d->ptype = *ptype; + /* default behaviour is to use all the bits */ + d->mask = 0x; + if (flags & SKBEDIT_F_MASK) + d->mask = *mask; d
[PATCH 6/8] batman-adv: Fix integer overflow in batadv_iv_ogm_calc_tq
From: Sven Eckelmann The undefined behavior sanatizer detected an signed integer overflow in a setup with near perfect link quality UBSAN: Undefined behaviour in net/batman-adv/bat_iv_ogm.c:1246:25 signed integer overflow: 8713350 * 255 cannot be represented in type 'int' The problems happens because the calculation of mixed unsigned and signed integers resulted in an integer multiplication. batadv_ogm_packet::tq (u8 255) * tq_own (u8 255) * tq_asym_penalty (int 134; max 255) * tq_iface_penalty (int 255; max 255) The tq_iface_penalty, tq_asym_penalty and inv_asym_penalty can just be changed to unsigned int because they are not expected to become negative. Fixes: c039876892e3 ("batman-adv: add WiFi penalty") Signed-off-by: Sven Eckelmann Signed-off-by: Marek Lindner Signed-off-by: Antonio Quartulli --- net/batman-adv/bat_iv_ogm.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/net/batman-adv/bat_iv_ogm.c b/net/batman-adv/bat_iv_ogm.c index 1b5bbafc0fa3..ce2f203048d3 100644 --- a/net/batman-adv/bat_iv_ogm.c +++ b/net/batman-adv/bat_iv_ogm.c @@ -1180,9 +1180,10 @@ static bool batadv_iv_ogm_calc_tq(struct batadv_orig_node *orig_node, u8 total_count; u8 orig_eq_count, neigh_rq_count, neigh_rq_inv, tq_own; unsigned int neigh_rq_inv_cube, neigh_rq_max_cube; - int tq_asym_penalty, inv_asym_penalty, if_num; + int if_num; + unsigned int tq_asym_penalty, inv_asym_penalty; unsigned int combined_tq; - int tq_iface_penalty; + unsigned int tq_iface_penalty; bool ret = false; /* find corresponding one hop neighbor */ -- 2.8.2
[PATCH 1/8] batman-adv: fix skb deref after free
From: Florian Westphal batadv_send_skb_to_orig() calls dev_queue_xmit() so we can't use skb->len. Fixes: 953324776d6d ("batman-adv: network coding - buffer unicast packets before forward") Signed-off-by: Florian Westphal Reviewed-by: Sven Eckelmann Signed-off-by: Marek Lindner Signed-off-by: Antonio Quartulli --- net/batman-adv/routing.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/net/batman-adv/routing.c b/net/batman-adv/routing.c index ae850f2d11cb..e3857ed4057f 100644 --- a/net/batman-adv/routing.c +++ b/net/batman-adv/routing.c @@ -601,6 +601,7 @@ static int batadv_route_unicast_packet(struct sk_buff *skb, struct batadv_unicast_packet *unicast_packet; struct ethhdr *ethhdr = eth_hdr(skb); int res, hdr_len, ret = NET_RX_DROP; + unsigned int len; unicast_packet = (struct batadv_unicast_packet *)skb->data; @@ -641,6 +642,7 @@ static int batadv_route_unicast_packet(struct sk_buff *skb, if (hdr_len > 0) batadv_skb_set_priority(skb, hdr_len); + len = skb->len; res = batadv_send_skb_to_orig(skb, orig_node, recv_if); /* translate transmit result into receive result */ @@ -648,7 +650,7 @@ static int batadv_route_unicast_packet(struct sk_buff *skb, /* skb was transmitted and consumed */ batadv_inc_counter(bat_priv, BATADV_CNT_FORWARD); batadv_add_counter(bat_priv, BATADV_CNT_FORWARD_BYTES, - skb->len + ETH_HLEN); + len + ETH_HLEN); ret = NET_RX_SUCCESS; } else if (res == NET_XMIT_POLICED) { -- 2.8.2
[PATCH 8/8] batman-adv: initialize ELP orig address on secondary interfaces
From: Marek Lindner This fix prevents nodes to wrongly create a 00:00:00:00:00:00 originator which can potentially interfere with the rest of the neighbor statistics. Fixes: d6f94d91f766 ("batman-adv: ELP - adding basic infrastructure") Signed-off-by: Marek Lindner Signed-off-by: Antonio Quartulli --- net/batman-adv/bat_v.c | 10 ++ net/batman-adv/bat_v_elp.c | 31 ++- net/batman-adv/bat_v_elp.h | 2 ++ 3 files changed, 34 insertions(+), 9 deletions(-) diff --git a/net/batman-adv/bat_v.c b/net/batman-adv/bat_v.c index 31bc57e2a944..0a12e5cdd65d 100644 --- a/net/batman-adv/bat_v.c +++ b/net/batman-adv/bat_v.c @@ -40,6 +40,16 @@ static void batadv_v_iface_activate(struct batadv_hard_iface *hard_iface) { + struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface); + struct batadv_hard_iface *primary_if; + + primary_if = batadv_primary_if_get_selected(bat_priv); + + if (primary_if) { + batadv_v_elp_iface_activate(primary_if, hard_iface); + batadv_hardif_put(primary_if); + } + /* B.A.T.M.A.N. V does not use any queuing mechanism, therefore it can * set the interface as ACTIVE right away, without any risk of race * condition diff --git a/net/batman-adv/bat_v_elp.c b/net/batman-adv/bat_v_elp.c index 3844e7efd0b0..df42eb1365a0 100644 --- a/net/batman-adv/bat_v_elp.c +++ b/net/batman-adv/bat_v_elp.c @@ -377,6 +377,27 @@ void batadv_v_elp_iface_disable(struct batadv_hard_iface *hard_iface) } /** + * batadv_v_elp_iface_activate - update the ELP buffer belonging to the given + * hard-interface + * @primary_iface: the new primary interface + * @hard_iface: interface holding the to-be-updated buffer + */ +void batadv_v_elp_iface_activate(struct batadv_hard_iface *primary_iface, +struct batadv_hard_iface *hard_iface) +{ + struct batadv_elp_packet *elp_packet; + struct sk_buff *skb; + + if (!hard_iface->bat_v.elp_skb) + return; + + skb = hard_iface->bat_v.elp_skb; + elp_packet = (struct batadv_elp_packet *)skb->data; + ether_addr_copy(elp_packet->orig, + primary_iface->net_dev->dev_addr); +} + +/** * batadv_v_elp_primary_iface_set - change internal data to reflect the new * primary interface * @primary_iface: the new primary interface @@ -384,8 +405,6 @@ void batadv_v_elp_iface_disable(struct batadv_hard_iface *hard_iface) void batadv_v_elp_primary_iface_set(struct batadv_hard_iface *primary_iface) { struct batadv_hard_iface *hard_iface; - struct batadv_elp_packet *elp_packet; - struct sk_buff *skb; /* update orig field of every elp iface belonging to this mesh */ rcu_read_lock(); @@ -393,13 +412,7 @@ void batadv_v_elp_primary_iface_set(struct batadv_hard_iface *primary_iface) if (primary_iface->soft_iface != hard_iface->soft_iface) continue; - if (!hard_iface->bat_v.elp_skb) - continue; - - skb = hard_iface->bat_v.elp_skb; - elp_packet = (struct batadv_elp_packet *)skb->data; - ether_addr_copy(elp_packet->orig, - primary_iface->net_dev->dev_addr); + batadv_v_elp_iface_activate(primary_iface, hard_iface); } rcu_read_unlock(); } diff --git a/net/batman-adv/bat_v_elp.h b/net/batman-adv/bat_v_elp.h index e95f1bca0785..cc130b2d05e5 100644 --- a/net/batman-adv/bat_v_elp.h +++ b/net/batman-adv/bat_v_elp.h @@ -25,6 +25,8 @@ struct work_struct; int batadv_v_elp_iface_enable(struct batadv_hard_iface *hard_iface); void batadv_v_elp_iface_disable(struct batadv_hard_iface *hard_iface); +void batadv_v_elp_iface_activate(struct batadv_hard_iface *primary_iface, +struct batadv_hard_iface *hard_iface); void batadv_v_elp_primary_iface_set(struct batadv_hard_iface *primary_iface); int batadv_v_elp_packet_recv(struct sk_buff *skb, struct batadv_hard_iface *if_incoming); -- 2.8.2
[PATCH 5/8] batman-adv: make sure ELP/OGM orig MAC is updated on address change
When the MAC address of the primary interface is changed, update the originator address in the ELP and OGM skb buffers as well in order to reflect the change. Fixes: d6f94d91f766 ("batman-adv: ELP - adding basic infrastructure") Reported-by: Marek Lindner Signed-off-by: Antonio Quartulli --- net/batman-adv/bat_v.c | 26 ++ 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/net/batman-adv/bat_v.c b/net/batman-adv/bat_v.c index 4f626a6b8ebd..31bc57e2a944 100644 --- a/net/batman-adv/bat_v.c +++ b/net/batman-adv/bat_v.c @@ -73,16 +73,34 @@ static void batadv_v_iface_disable(struct batadv_hard_iface *hard_iface) batadv_v_elp_iface_disable(hard_iface); } -static void batadv_v_iface_update_mac(struct batadv_hard_iface *hard_iface) -{ -} - static void batadv_v_primary_iface_set(struct batadv_hard_iface *hard_iface) { batadv_v_elp_primary_iface_set(hard_iface); batadv_v_ogm_primary_iface_set(hard_iface); } +/** + * batadv_v_iface_update_mac - react to hard-interface MAC address change + * @hard_iface: the modified interface + * + * If the modified interface is the primary one, update the originator + * address in the ELP and OGM messages to reflect the new MAC address. + */ +static void batadv_v_iface_update_mac(struct batadv_hard_iface *hard_iface) +{ + struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface); + struct batadv_hard_iface *primary_if; + + primary_if = batadv_primary_if_get_selected(bat_priv); + if (primary_if != hard_iface) + goto out; + + batadv_v_primary_iface_set(hard_iface); +out: + if (primary_if) + batadv_hardif_put(primary_if); +} + static void batadv_v_hardif_neigh_init(struct batadv_hardif_neigh_node *hardif_neigh) { -- 2.8.2
[PATCH 4/8] batman-adv: Fix unexpected free of bcast_own on add_if error
From: Sven Eckelmann The function batadv_iv_ogm_orig_add_if allocates new buffers for bcast_own and bcast_own_sum. It is expected that these buffers are unchanged in case either bcast_own or bcast_own_sum couldn't be resized. But the error handling of this function frees the already resized buffer for bcast_own when the allocation of the new bcast_own_sum buffer failed. This will lead to an invalid memory access when some code will try to access bcast_own. Instead the resized new bcast_own buffer has to be kept. This will not lead to problems because the size of the buffer was only increased and therefore no user of the buffer will try to access bytes outside of the new buffer. Fixes: d0015fdd3d2c ("batman-adv: provide orig_node routing API") Signed-off-by: Sven Eckelmann Signed-off-by: Marek Lindner Signed-off-by: Antonio Quartulli --- net/batman-adv/bat_iv_ogm.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/net/batman-adv/bat_iv_ogm.c b/net/batman-adv/bat_iv_ogm.c index 7f98a9d39883..1b5bbafc0fa3 100644 --- a/net/batman-adv/bat_iv_ogm.c +++ b/net/batman-adv/bat_iv_ogm.c @@ -157,10 +157,8 @@ static int batadv_iv_ogm_orig_add_if(struct batadv_orig_node *orig_node, orig_node->bat_iv.bcast_own = data_ptr; data_ptr = kmalloc_array(max_if_num, sizeof(u8), GFP_ATOMIC); - if (!data_ptr) { - kfree(orig_node->bat_iv.bcast_own); + if (!data_ptr) goto unlock; - } memcpy(data_ptr, orig_node->bat_iv.bcast_own_sum, (max_if_num - 1) * sizeof(u8)); -- 2.8.2
[PATCH 3/8] batman-adv: Fix refcnt leak in batadv_v_neigh_*
From: Sven Eckelmann The functions batadv_neigh_ifinfo_get increase the reference counter of the batadv_neigh_ifinfo. These have to be reduced again when the reference is not used anymore to correctly free the objects. Fixes: 9786906022eb ("batman-adv: B.A.T.M.A.N. V - implement neighbor comparison API calls") Signed-off-by: Sven Eckelmann Signed-off-by: Marek Lindner Signed-off-by: Antonio Quartulli --- net/batman-adv/bat_v.c | 32 +--- 1 file changed, 25 insertions(+), 7 deletions(-) diff --git a/net/batman-adv/bat_v.c b/net/batman-adv/bat_v.c index 50bfcf87f569..4f626a6b8ebd 100644 --- a/net/batman-adv/bat_v.c +++ b/net/batman-adv/bat_v.c @@ -256,14 +256,23 @@ static int batadv_v_neigh_cmp(struct batadv_neigh_node *neigh1, struct batadv_hard_iface *if_outgoing2) { struct batadv_neigh_ifinfo *ifinfo1, *ifinfo2; + int ret = 0; ifinfo1 = batadv_neigh_ifinfo_get(neigh1, if_outgoing1); + if (WARN_ON(!ifinfo1)) + goto err_ifinfo1; + ifinfo2 = batadv_neigh_ifinfo_get(neigh2, if_outgoing2); + if (WARN_ON(!ifinfo2)) + goto err_ifinfo2; - if (WARN_ON(!ifinfo1 || !ifinfo2)) - return 0; + ret = ifinfo1->bat_v.throughput - ifinfo2->bat_v.throughput; - return ifinfo1->bat_v.throughput - ifinfo2->bat_v.throughput; + batadv_neigh_ifinfo_put(ifinfo2); +err_ifinfo2: + batadv_neigh_ifinfo_put(ifinfo1); +err_ifinfo1: + return ret; } static bool batadv_v_neigh_is_sob(struct batadv_neigh_node *neigh1, @@ -273,17 +282,26 @@ static bool batadv_v_neigh_is_sob(struct batadv_neigh_node *neigh1, { struct batadv_neigh_ifinfo *ifinfo1, *ifinfo2; u32 threshold; + bool ret = false; ifinfo1 = batadv_neigh_ifinfo_get(neigh1, if_outgoing1); - ifinfo2 = batadv_neigh_ifinfo_get(neigh2, if_outgoing2); + if (WARN_ON(!ifinfo1)) + goto err_ifinfo1; - if (WARN_ON(!ifinfo1 || !ifinfo2)) - return false; + ifinfo2 = batadv_neigh_ifinfo_get(neigh2, if_outgoing2); + if (WARN_ON(!ifinfo2)) + goto err_ifinfo2; threshold = ifinfo1->bat_v.throughput / 4; threshold = ifinfo1->bat_v.throughput - threshold; - return ifinfo2->bat_v.throughput > threshold; + ret = ifinfo2->bat_v.throughput > threshold; + + batadv_neigh_ifinfo_put(ifinfo2); +err_ifinfo2: + batadv_neigh_ifinfo_put(ifinfo1); +err_ifinfo1: + return ret; } static struct batadv_algo_ops batadv_batman_v __read_mostly = { -- 2.8.2
[PATCH 2/8] batman-adv: Avoid nullptr derefence in batadv_v_neigh_is_sob
From: Sven Eckelmann batadv_neigh_ifinfo_get can return NULL when it cannot find (even when only temporarily) anymore the neigh_ifinfo in the list neigh->ifinfo_list. This has to be checked to avoid kernel Oopses when the ifinfo is dereferenced. This a situation which isn't expected but is already handled by functions like batadv_v_neigh_cmp. The same kind of warning is therefore used before the function returns without dereferencing the pointers. Fixes: 9786906022eb ("batman-adv: B.A.T.M.A.N. V - implement neighbor comparison API calls") Signed-off-by: Sven Eckelmann Signed-off-by: Marek Lindner Signed-off-by: Antonio Quartulli --- net/batman-adv/bat_v.c | 4 1 file changed, 4 insertions(+) diff --git a/net/batman-adv/bat_v.c b/net/batman-adv/bat_v.c index 3ff8bd1b7bdc..50bfcf87f569 100644 --- a/net/batman-adv/bat_v.c +++ b/net/batman-adv/bat_v.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include @@ -276,6 +277,9 @@ static bool batadv_v_neigh_is_sob(struct batadv_neigh_node *neigh1, ifinfo1 = batadv_neigh_ifinfo_get(neigh1, if_outgoing1); ifinfo2 = batadv_neigh_ifinfo_get(neigh2, if_outgoing2); + if (WARN_ON(!ifinfo1 || !ifinfo2)) + return false; + threshold = ifinfo1->bat_v.throughput / 4; threshold = ifinfo1->bat_v.throughput - threshold; -- 2.8.2
[PATCH 7/8] batman-adv: Avoid duplicate neigh_node additions
From: Linus Lüssing Two parallel calls to batadv_neigh_node_new() might race for creating and adding the same neig_node. Fix this by including the check for any already existing, identical neigh_node within the spin-lock. This fixes splats like the following: [ 739.535069] [ cut here ] [ 739.535079] WARNING: CPU: 0 PID: 0 at /usr/src/batman-adv/git/batman-adv/net/batman-adv/bat_iv_ogm.c:1004 batadv_iv_ogm_process_per_outif+0xe3f/0xe60 [batman_adv]() [ 739.535092] too many matching neigh_nodes [ 739.535094] Modules linked in: dm_mod tun ip6table_filter ip6table_mangle ip6table_nat nf_nat_ipv6 ip6_tables xt_nat iptable_nat nf_nat_ipv4 nf_nat xt_TCPMSS xt_mark iptable_mangle xt_tcpudp xt_conntrack iptable_filter ip_tables x_tables ip_gre ip_tunnel gre bridge stp llc thermal_sys kvm_intel kvm crct10dif_pclmul crc32_pclmul sha256_ssse3 sha256_generic hmac drbg ansi_cprng aesni_intel aes_x86_64 lrw gf128mul glue_helper ablk_helper cryptd evdev pcspkr ip6_gre ip6_tunnel tunnel6 batman_adv(O) libcrc32c nf_conntrack_ipv6 nf_defrag_ipv6 nf_conntrack_ipv4 nf_defrag_ipv4 nf_conntrack autofs4 ext4 crc16 mbcache jbd2 xen_netfront xen_blkfront crc32c_intel [ 739.535177] CPU: 0 PID: 0 Comm: swapper/0 Tainted: GW O 4.2.0-0.bpo.1-amd64 #1 Debian 4.2.6-3~bpo8+2 [ 739.535186] a013b050 81554521 88007d003c18 [ 739.535201] 8106fa01 8800047a087a 880079c3a000 [ 739.735602] 88007b82bf40 88007bc2d1c0 8106fa7a a013aa8e [ 739.735624] Call Trace: [ 739.735639][] ? dump_stack+0x40/0x50 [ 739.735677] [] ? warn_slowpath_common+0x81/0xb0 [ 739.735692] [] ? warn_slowpath_fmt+0x4a/0x50 [ 739.735715] [] ? batadv_iv_ogm_process_per_outif+0xe3f/0xe60 [batman_adv] [ 739.735740] [] ? batadv_iv_ogm_receive+0x363/0x380 [batman_adv] [ 739.735762] [] ? batadv_iv_ogm_receive+0x363/0x380 [batman_adv] [ 739.735783] [] ? __raw_callee_save___pv_queued_spin_unlock+0x11/0x20 [ 739.735804] [] ? batadv_batman_skb_recv+0xc9/0x110 [batman_adv] [ 739.735825] [] ? __netif_receive_skb_core+0x841/0x9a0 [ 739.735838] [] ? __raw_callee_save___pv_queued_spin_unlock+0x11/0x20 [ 739.735853] [] ? process_backlog+0xa1/0x140 [ 739.735864] [] ? net_rx_action+0x20a/0x320 [ 739.735878] [] ? __do_softirq+0x107/0x270 [ 739.735891] [] ? irq_exit+0x92/0xa0 [ 739.735905] [] ? xen_evtchn_do_upcall+0x31/0x40 [ 739.735924] [] ? xen_do_hypervisor_callback+0x1e/0x40 [ 739.735939][] ? xen_hypercall_sched_op+0xa/0x20 [ 739.735965] [] ? xen_hypercall_sched_op+0xa/0x20 [ 739.735979] [] ? xen_safe_halt+0xc/0x20 [ 739.735991] [] ? default_idle+0x1c/0xa0 [ 739.736004] [] ? cpu_startup_entry+0x2eb/0x350 [ 739.736019] [] ? start_kernel+0x480/0x48b [ 739.736032] [] ? xen_start_kernel+0x507/0x511 [ 739.736048] ---[ end trace c106bb901244bc8c ]--- Fixes: f987ed6ebd99 ("batman-adv: protect neighbor list with rcu locks") Reported-by: Martin Weinelt Signed-off-by: Linus Lüssing Signed-off-by: Marek Lindner Signed-off-by: Antonio Quartulli --- net/batman-adv/originator.c | 6 -- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/net/batman-adv/originator.c b/net/batman-adv/originator.c index 1ff4ee473966..7f51bc2c06eb 100644 --- a/net/batman-adv/originator.c +++ b/net/batman-adv/originator.c @@ -619,6 +619,8 @@ batadv_neigh_node_new(struct batadv_orig_node *orig_node, struct batadv_neigh_node *neigh_node; struct batadv_hardif_neigh_node *hardif_neigh = NULL; + spin_lock_bh(&orig_node->neigh_list_lock); + neigh_node = batadv_neigh_node_get(orig_node, hard_iface, neigh_addr); if (neigh_node) goto out; @@ -650,15 +652,15 @@ batadv_neigh_node_new(struct batadv_orig_node *orig_node, kref_init(&neigh_node->refcount); kref_get(&neigh_node->refcount); - spin_lock_bh(&orig_node->neigh_list_lock); hlist_add_head_rcu(&neigh_node->list, &orig_node->neigh_list); - spin_unlock_bh(&orig_node->neigh_list_lock); batadv_dbg(BATADV_DBG_BATMAN, orig_node->bat_priv, "Creating new neighbor %pM for orig_node %pM on interface %s\n", neigh_addr, orig_node->orig, hard_iface->net_dev->name); out: + spin_unlock_bh(&orig_node->neigh_list_lock); + if (hardif_neigh) batadv_hardif_neigh_put(hardif_neigh); return neigh_node; -- 2.8.2
pull request: batman-adv 20160518
Hi David, these are the fixes that couldn't make it for linux-4.6 rebased on top of net-next. They were all supposed to be applied on 4.6, therefore it would be nice if you could queue them for inclusion in the 4.6.1 stable release. Please pull or let me know of any problem! I also have a question: I have another bugfix that should only be applied to 4.6 and not to 4.7/net-next - should I directly send it to sta...@vger.kernel.org ? Thanks a lot, Antonio The following changes since commit 917fa5353da05e8a0045b8acacba8d50400d5b12: Revert "phy dp83867: Fix compilation with CONFIG_OF_MDIO=m" (2016-05-17 14:49:55 -0400) are available in the git repository at: git://git.open-mesh.org/linux-merge.git tags/batman-adv-fix-for-davem for you to fetch changes up to ebe24cea95ab969f76f2922032f6c390fdc816f2: batman-adv: initialize ELP orig address on secondary interfaces (2016-05-18 11:49:44 +0800) During the Wireless Battle Mesh v9 in Porto (PT) at the beginning of May, we managed to uncover and fix some important bugs in our new B.A.T.M.A.N. V algorithm. These are the fixes we came up with together with others that I collected in the past weeks: - avoid potential crash due to NULL pointer dereference in B.A.T.M.A.N. V routine when a neigh_ifinfo object is not found, by Sven Eckelmann - avoid use-after-free of skb when counting outgoing bytes, by Florian Westphal - fix neigh_ifinfo object reference counting imbalance when using B.A.T.M.A.N. V, by Sven Eckelmann. Such imbalance may lead to the impossibility of releasing the related netdev object on shutdown - avoid invalid memory access in case of error while allocating bcast_own_sum when a new hard-interface is added, by Sven Eckelmann - ensure originator address is updated in OMG/ELP packet content upon primary interface address change, by Antonio Quartulli - fix integer overflow when computing TQ metric (B.A.T.M.A.N. IV), by Sven Eckelmann - avoid race condition while adding new neigh_node which would result in having two objects mapping to the same physical neighbour, by Linus Lüssing - ensure originator address is initialized in ELP packet content on secondary interfaces, by Marek Lindner -------- Antonio Quartulli (1): batman-adv: make sure ELP/OGM orig MAC is updated on address change Florian Westphal (1): batman-adv: fix skb deref after free Linus Lüssing (1): batman-adv: Avoid duplicate neigh_node additions Marek Lindner (1): batman-adv: initialize ELP orig address on secondary interfaces Sven Eckelmann (4): batman-adv: Avoid nullptr derefence in batadv_v_neigh_is_sob batman-adv: Fix refcnt leak in batadv_v_neigh_* batman-adv: Fix unexpected free of bcast_own on add_if error batman-adv: Fix integer overflow in batadv_iv_ogm_calc_tq net/batman-adv/bat_iv_ogm.c | 9 +++ net/batman-adv/bat_v.c | 66 +++-- net/batman-adv/bat_v_elp.c | 31 ++--- net/batman-adv/bat_v_elp.h | 2 ++ net/batman-adv/originator.c | 6 +++-- net/batman-adv/routing.c| 4 ++- 6 files changed, 93 insertions(+), 25 deletions(-)
[PATCH 4/4] batman-adv: Fix refcnt leak in batadv_v_neigh_*
From: Sven Eckelmann The functions batadv_neigh_ifinfo_get increase the reference counter of the batadv_neigh_ifinfo. These have to be reduced again when the reference is not used anymore to correctly free the objects. Fixes: 9786906022eb ("batman-adv: B.A.T.M.A.N. V - implement neighbor comparison API calls") Signed-off-by: Sven Eckelmann Signed-off-by: Marek Lindner Signed-off-by: Antonio Quartulli --- net/batman-adv/bat_v.c | 32 +--- 1 file changed, 25 insertions(+), 7 deletions(-) diff --git a/net/batman-adv/bat_v.c b/net/batman-adv/bat_v.c index e81ad4b8e5c8..7fd477583eb0 100644 --- a/net/batman-adv/bat_v.c +++ b/net/batman-adv/bat_v.c @@ -257,14 +257,23 @@ static int batadv_v_neigh_cmp(struct batadv_neigh_node *neigh1, struct batadv_hard_iface *if_outgoing2) { struct batadv_neigh_ifinfo *ifinfo1, *ifinfo2; + int ret = 0; ifinfo1 = batadv_neigh_ifinfo_get(neigh1, if_outgoing1); + if (WARN_ON(!ifinfo1)) + goto err_ifinfo1; + ifinfo2 = batadv_neigh_ifinfo_get(neigh2, if_outgoing2); + if (WARN_ON(!ifinfo2)) + goto err_ifinfo2; - if (WARN_ON(!ifinfo1 || !ifinfo2)) - return 0; + ret = ifinfo1->bat_v.throughput - ifinfo2->bat_v.throughput; - return ifinfo1->bat_v.throughput - ifinfo2->bat_v.throughput; + batadv_neigh_ifinfo_put(ifinfo2); +err_ifinfo2: + batadv_neigh_ifinfo_put(ifinfo1); +err_ifinfo1: + return ret; } static bool batadv_v_neigh_is_sob(struct batadv_neigh_node *neigh1, @@ -274,17 +283,26 @@ static bool batadv_v_neigh_is_sob(struct batadv_neigh_node *neigh1, { struct batadv_neigh_ifinfo *ifinfo1, *ifinfo2; u32 threshold; + bool ret = false; ifinfo1 = batadv_neigh_ifinfo_get(neigh1, if_outgoing1); - ifinfo2 = batadv_neigh_ifinfo_get(neigh2, if_outgoing2); + if (WARN_ON(!ifinfo1)) + goto err_ifinfo1; - if (WARN_ON(!ifinfo1 || !ifinfo2)) - return false; + ifinfo2 = batadv_neigh_ifinfo_get(neigh2, if_outgoing2); + if (WARN_ON(!ifinfo2)) + goto err_ifinfo2; threshold = ifinfo1->bat_v.throughput / 4; threshold = ifinfo1->bat_v.throughput - threshold; - return ifinfo2->bat_v.throughput > threshold; + ret = ifinfo2->bat_v.throughput > threshold; + + batadv_neigh_ifinfo_put(ifinfo2); +err_ifinfo2: + batadv_neigh_ifinfo_put(ifinfo1); +err_ifinfo1: + return ret; } static struct batadv_algo_ops batadv_batman_v __read_mostly = { -- 2.8.2
[PATCH 3/4] batman-adv: Fix double neigh_node_put in batadv_v_ogm_route_update
From: Sven Eckelmann The router is put down twice when it was non-NULL and either orig_ifinfo is NULL afterwards or batman-adv receives a packet with the same sequence number. This will end up in a use-after-free when the batadv_neigh_node is removed because the reference counter ended up too early at 0. Fixes: 9323158ef9f4 ("batman-adv: OGMv2 - implement originators logic") Signed-off-by: Sven Eckelmann Signed-off-by: Antonio Quartulli --- net/batman-adv/bat_v_ogm.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/net/batman-adv/bat_v_ogm.c b/net/batman-adv/bat_v_ogm.c index d9bcbe6e7d65..91df28a100f9 100644 --- a/net/batman-adv/bat_v_ogm.c +++ b/net/batman-adv/bat_v_ogm.c @@ -529,8 +529,10 @@ static void batadv_v_ogm_route_update(struct batadv_priv *bat_priv, goto out; } - if (router) + if (router) { batadv_neigh_node_put(router); + router = NULL; + } /* Update routes, and check if the OGM is from the best next hop */ batadv_v_ogm_orig_update(bat_priv, orig_node, neigh_node, ogm2, -- 2.8.2
[PATCH 2/4] batman-adv: Avoid nullptr derefence in batadv_v_neigh_is_sob
From: Sven Eckelmann batadv_neigh_ifinfo_get can return NULL when it cannot find (even when only temporarily) anymore the neigh_ifinfo in the list neigh->ifinfo_list. This has to be checked to avoid kernel Oopses when the ifinfo is dereferenced. This a situation which isn't expected but is already handled by functions like batadv_v_neigh_cmp. The same kind of warning is therefore used before the function returns without dereferencing the pointers. Fixes: 9786906022eb ("batman-adv: B.A.T.M.A.N. V - implement neighbor comparison API calls") Signed-off-by: Sven Eckelmann Signed-off-by: Marek Lindner Signed-off-by: Antonio Quartulli --- net/batman-adv/bat_v.c | 4 1 file changed, 4 insertions(+) diff --git a/net/batman-adv/bat_v.c b/net/batman-adv/bat_v.c index 4026f198a734..e81ad4b8e5c8 100644 --- a/net/batman-adv/bat_v.c +++ b/net/batman-adv/bat_v.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include @@ -277,6 +278,9 @@ static bool batadv_v_neigh_is_sob(struct batadv_neigh_node *neigh1, ifinfo1 = batadv_neigh_ifinfo_get(neigh1, if_outgoing1); ifinfo2 = batadv_neigh_ifinfo_get(neigh2, if_outgoing2); + if (WARN_ON(!ifinfo1 || !ifinfo2)) + return false; + threshold = ifinfo1->bat_v.throughput / 4; threshold = ifinfo1->bat_v.throughput - threshold; -- 2.8.2
pull request [net]: batman-adv 20160515
Hello David, although we are extremely late in the release cycle we have 4 fixes which would really be worth merging before releasing linux-4.6. As you can read in the git tag below, each of them can lead to a kernel crash or to an unstable system. We came up with several fixes after having tested our new B.A.T.M.A.N. V code at the Wireless Battle Mesh in Porto (PT) at the beginning of the month, however, what I am sending here is the minimum subset that we though being extremely important to avoid easy kernel crashes. The change footprint is also rather small. Please pull or let me know if you rather prefer to get this through net-next. If you decide to pull, you will hit some conflicts when merging net into net-next, but I can send you some instructions to ease the process. Thanks a lot! Antonio The following changes since commit b91506586206140154b0b44cccf88c8cc0a4dca5: Merge branch 'xgene-fixes' (2016-05-13 21:12:07 -0400) are available in the git repository at: git://git.open-mesh.org/linux-merge.git tags/batman-adv-fix-for-davem for you to fetch changes up to 6b892c1cb0805acee5d4ddd9e7878ed076c1b7c7: batman-adv: Fix refcnt leak in batadv_v_neigh_* (2016-05-14 15:51:39 +0800) During the Wireless Battle Mesh v9 in Porto (PT) at the beginning of May, we managed to uncover and fix some important bugs in our new B.A.T.M.A.N. V algorithm. These are the most critical fixes we came up with aimed to avoid easy kernel crashes: - avoid potential crash due to NULL pointer dereference in B.A.T.M.A.N. V routine when a neigh_ifinfo object is not found, by Sven Eckelmann - avoid crash due to double kref_put on neigh_node object in B.A.T.M.A.N. V routine leading to use-after-free, by Sven Eckelmann (this crash can be always replicated) - avoid use-after-free of skb when counting outgoing bytes, by Florian Westphal - fix neigh_ifinfo object reference counting imbalance when using B.A.T.M.A.N. V, by Sven Eckelmann. Such imbalance may lead to the impossibility of releasing the related netdev object on shutdown. Florian Westphal (1): batman-adv: fix skb deref after free Sven Eckelmann (3): batman-adv: Avoid nullptr derefence in batadv_v_neigh_is_sob batman-adv: Fix double neigh_node_put in batadv_v_ogm_route_update batman-adv: Fix refcnt leak in batadv_v_neigh_* net/batman-adv/bat_v.c | 30 ++ net/batman-adv/bat_v_ogm.c | 4 +++- net/batman-adv/routing.c | 4 +++- 3 files changed, 32 insertions(+), 6 deletions(-)
[PATCH 1/4] batman-adv: fix skb deref after free
From: Florian Westphal batadv_send_skb_to_orig() calls dev_queue_xmit() so we can't use skb->len. Fixes: 953324776d6d ("batman-adv: network coding - buffer unicast packets before forward") Signed-off-by: Florian Westphal Reviewed-by: Sven Eckelmann Signed-off-by: Marek Lindner Signed-off-by: Antonio Quartulli --- net/batman-adv/routing.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/net/batman-adv/routing.c b/net/batman-adv/routing.c index b781bf753250..0c0c30e101a1 100644 --- a/net/batman-adv/routing.c +++ b/net/batman-adv/routing.c @@ -601,6 +601,7 @@ static int batadv_route_unicast_packet(struct sk_buff *skb, struct batadv_unicast_packet *unicast_packet; struct ethhdr *ethhdr = eth_hdr(skb); int res, hdr_len, ret = NET_RX_DROP; + unsigned int len; unicast_packet = (struct batadv_unicast_packet *)skb->data; @@ -641,6 +642,7 @@ static int batadv_route_unicast_packet(struct sk_buff *skb, if (hdr_len > 0) batadv_skb_set_priority(skb, hdr_len); + len = skb->len; res = batadv_send_skb_to_orig(skb, orig_node, recv_if); /* translate transmit result into receive result */ @@ -648,7 +650,7 @@ static int batadv_route_unicast_packet(struct sk_buff *skb, /* skb was transmitted and consumed */ batadv_inc_counter(bat_priv, BATADV_CNT_FORWARD); batadv_add_counter(bat_priv, BATADV_CNT_FORWARD_BYTES, - skb->len + ETH_HLEN); + len + ETH_HLEN); ret = NET_RX_SUCCESS; } else if (res == NET_XMIT_POLICED) { -- 2.8.2
[PATCH 14/17] batman-adv: Use kref_get for _batadv_update_route
From: Sven Eckelmann _batadv_update_route requires that the caller already has a valid reference for neigh_node. It is therefore not possible that it has an reference counter of 0 and was still given to this function The kref_get function instead WARNs (with debug information) when the reference counter would still be 0. This makes a bug in batman-adv better visible because kref_get_unless_zero would have ignored this problem. Signed-off-by: Sven Eckelmann Signed-off-by: Marek Lindner Signed-off-by: Antonio Quartulli --- net/batman-adv/routing.c | 8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/net/batman-adv/routing.c b/net/batman-adv/routing.c index 2ecfca246be4..b494e435686f 100644 --- a/net/batman-adv/routing.c +++ b/net/batman-adv/routing.c @@ -100,10 +100,6 @@ static void _batadv_update_route(struct batadv_priv *bat_priv, if (curr_router) batadv_neigh_node_put(curr_router); - /* increase refcount of new best neighbor */ - if (neigh_node && !kref_get_unless_zero(&neigh_node->refcount)) - neigh_node = NULL; - spin_lock_bh(&orig_node->neigh_list_lock); /* curr_router used earlier may not be the current orig_ifinfo->router * anymore because it was dereferenced outside of the neigh_list_lock @@ -114,6 +110,10 @@ static void _batadv_update_route(struct batadv_priv *bat_priv, */ curr_router = rcu_dereference_protected(orig_ifinfo->router, true); + /* increase refcount of new best neighbor */ + if (neigh_node) + kref_get(&neigh_node->refcount); + rcu_assign_pointer(orig_ifinfo->router, neigh_node); spin_unlock_bh(&orig_node->neigh_list_lock); batadv_orig_ifinfo_put(orig_ifinfo); -- 2.8.2
[PATCH 15/17] batman-adv: Use bool as return type for boolean functions
From: Sven Eckelmann It is easier to understand that the returned value of a specific function doesn't have to be 0 when the functions was successful when the actual return type is bool. This is especially true when all surrounding functions with return type int use negative values to return the error code. Reported-by: Nicholas Krause Signed-off-by: Sven Eckelmann Signed-off-by: Marek Lindner Signed-off-by: Antonio Quartulli --- net/batman-adv/bat_iv_ogm.c| 23 ++--- net/batman-adv/bitarray.c | 16 +-- net/batman-adv/bitarray.h | 15 +-- net/batman-adv/bridge_loop_avoidance.c | 175 + net/batman-adv/bridge_loop_avoidance.h | 43 net/batman-adv/debugfs.c | 2 +- net/batman-adv/distributed-arp-table.c | 6 +- net/batman-adv/hard-interface.c| 15 ++- net/batman-adv/hash.h | 6 +- net/batman-adv/main.h | 2 +- net/batman-adv/network-coding.c| 12 +-- net/batman-adv/originator.c| 4 +- net/batman-adv/originator.h| 2 +- net/batman-adv/routing.c | 37 +++ net/batman-adv/routing.h | 6 +- net/batman-adv/soft-interface.c| 6 +- net/batman-adv/soft-interface.h| 3 +- net/batman-adv/translation-table.c | 31 +++--- 18 files changed, 205 insertions(+), 199 deletions(-) diff --git a/net/batman-adv/bat_iv_ogm.c b/net/batman-adv/bat_iv_ogm.c index eb3435de54b5..7f98a9d39883 100644 --- a/net/batman-adv/bat_iv_ogm.c +++ b/net/batman-adv/bat_iv_ogm.c @@ -1168,13 +1168,13 @@ out: * @if_incoming: interface where the packet was received * @if_outgoing: interface for which the retransmission should be considered * - * Return: 1 if the link can be considered bidirectional, 0 otherwise + * Return: true if the link can be considered bidirectional, false otherwise */ -static int batadv_iv_ogm_calc_tq(struct batadv_orig_node *orig_node, -struct batadv_orig_node *orig_neigh_node, -struct batadv_ogm_packet *batadv_ogm_packet, -struct batadv_hard_iface *if_incoming, -struct batadv_hard_iface *if_outgoing) +static bool batadv_iv_ogm_calc_tq(struct batadv_orig_node *orig_node, + struct batadv_orig_node *orig_neigh_node, + struct batadv_ogm_packet *batadv_ogm_packet, + struct batadv_hard_iface *if_incoming, + struct batadv_hard_iface *if_outgoing) { struct batadv_priv *bat_priv = netdev_priv(if_incoming->soft_iface); struct batadv_neigh_node *neigh_node = NULL, *tmp_neigh_node; @@ -1182,9 +1182,10 @@ static int batadv_iv_ogm_calc_tq(struct batadv_orig_node *orig_node, u8 total_count; u8 orig_eq_count, neigh_rq_count, neigh_rq_inv, tq_own; unsigned int neigh_rq_inv_cube, neigh_rq_max_cube; - int tq_asym_penalty, inv_asym_penalty, if_num, ret = 0; + int tq_asym_penalty, inv_asym_penalty, if_num; unsigned int combined_tq; int tq_iface_penalty; + bool ret = false; /* find corresponding one hop neighbor */ rcu_read_lock(); @@ -1296,7 +1297,7 @@ static int batadv_iv_ogm_calc_tq(struct batadv_orig_node *orig_node, * consider it bidirectional */ if (batadv_ogm_packet->tq >= BATADV_TQ_TOTAL_BIDRECT_LIMIT) - ret = 1; + ret = true; out: if (neigh_node) @@ -1325,9 +1326,9 @@ batadv_iv_ogm_update_seqnos(const struct ethhdr *ethhdr, struct batadv_orig_ifinfo *orig_ifinfo = NULL; struct batadv_neigh_node *neigh_node; struct batadv_neigh_ifinfo *neigh_ifinfo; - int is_dup; + bool is_dup; s32 seq_diff; - int need_update = 0; + bool need_update = false; int set_mark; enum batadv_dup_status ret = BATADV_NO_DUP; u32 seqno = ntohl(batadv_ogm_packet->seqno); @@ -1437,7 +1438,7 @@ batadv_iv_ogm_process_per_outif(const struct sk_buff *skb, int ogm_offset, struct sk_buff *skb_priv; struct ethhdr *ethhdr; u8 *prev_sender; - int is_bidirect; + bool is_bidirect; /* create a private copy of the skb, as some functions change tq value * and/or flags. diff --git a/net/batman-adv/bitarray.c b/net/batman-adv/bitarray.c index b56bb000a0ab..a0c7913837a5 100644 --- a/net/batman-adv/bitarray.c +++ b/net/batman-adv/bitarray.c @@ -38,11 +38,11 @@ static void batadv_bitmap_shift_left(unsigned long *seq_bits, s32 n) * the last sequence number * @set_mark: whether this packet should be marked in seq_bits * - * Return: 1 if the window was moved (either new or very old), - * 0 if the window was not moved/shifted. + * Return: true if the window was moved (e
[PATCH 10/17] batman-adv: Use kref_get for batadv_nc_get_nc_node
From: Sven Eckelmann batadv_nc_get_nc_node requires that the caller already has a valid reference for orig_neigh_node. It is therefore not possible that it has an reference counter of 0 and was still given to this function The kref_get function instead WARNs (with debug information) when the reference counter would still be 0. This makes a bug in batman-adv better visible because kref_get_unless_zero would have ignored this problem. Signed-off-by: Sven Eckelmann Signed-off-by: Marek Lindner Signed-off-by: Antonio Quartulli --- net/batman-adv/network-coding.c | 7 +-- 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/net/batman-adv/network-coding.c b/net/batman-adv/network-coding.c index 1da8e0e1b18f..953dff1ad43b 100644 --- a/net/batman-adv/network-coding.c +++ b/net/batman-adv/network-coding.c @@ -856,8 +856,7 @@ batadv_nc_get_nc_node(struct batadv_priv *bat_priv, if (!nc_node) return NULL; - if (!kref_get_unless_zero(&orig_neigh_node->refcount)) - goto free; + kref_get(&orig_neigh_node->refcount); /* Initialize nc_node */ INIT_LIST_HEAD(&nc_node->list); @@ -884,10 +883,6 @@ batadv_nc_get_nc_node(struct batadv_priv *bat_priv, spin_unlock_bh(lock); return nc_node; - -free: - kfree(nc_node); - return NULL; } /** -- 2.8.2
[PATCH 13/17] batman-adv: Use kref_get for hard_iface subfunctions
From: Sven Eckelmann The callers of the functions using batadv_hard_iface objects already make sure that they hold a valid reference. The subfunctions don't have to check whether the reference counter is > 0 because this was checked by the callers. The kref_get function instead WARNs (with debug information) when the reference counter would still be 0. This makes a bug in batman-adv better visible because kref_get_unless_zero would have ignored this problem. Signed-off-by: Sven Eckelmann Signed-off-by: Marek Lindner Signed-off-by: Antonio Quartulli --- net/batman-adv/bat_iv_ogm.c | 14 +++--- net/batman-adv/hard-interface.c | 7 +++ net/batman-adv/originator.c | 30 +++--- 3 files changed, 13 insertions(+), 38 deletions(-) diff --git a/net/batman-adv/bat_iv_ogm.c b/net/batman-adv/bat_iv_ogm.c index 57e9962c7090..eb3435de54b5 100644 --- a/net/batman-adv/bat_iv_ogm.c +++ b/net/batman-adv/bat_iv_ogm.c @@ -681,18 +681,12 @@ static void batadv_iv_ogm_aggregate_new(const unsigned char *packet_buff, unsigned char *skb_buff; unsigned int skb_size; - if (!kref_get_unless_zero(&if_incoming->refcount)) - return; - - if (!kref_get_unless_zero(&if_outgoing->refcount)) - goto out_free_incoming; - /* own packet should always be scheduled */ if (!own_packet) { if (!batadv_atomic_dec_not_zero(&bat_priv->batman_queue_left)) { batadv_dbg(BATADV_DBG_BATMAN, bat_priv, "batman packet queue full\n"); - goto out_free_outgoing; + return; } } @@ -718,6 +712,8 @@ static void batadv_iv_ogm_aggregate_new(const unsigned char *packet_buff, forw_packet_aggr->packet_len = packet_len; memcpy(skb_buff, packet_buff, packet_len); + kref_get(&if_incoming->refcount); + kref_get(&if_outgoing->refcount); forw_packet_aggr->own = own_packet; forw_packet_aggr->if_incoming = if_incoming; forw_packet_aggr->if_outgoing = if_outgoing; @@ -747,10 +743,6 @@ out_free_forw_packet: out_nomem: if (!own_packet) atomic_inc(&bat_priv->batman_queue_left); -out_free_outgoing: - batadv_hardif_put(if_outgoing); -out_free_incoming: - batadv_hardif_put(if_incoming); } /* aggregate a new packet into the existing ogm packet */ diff --git a/net/batman-adv/hard-interface.c b/net/batman-adv/hard-interface.c index d3d37f3f99cf..7c1d8d7ac548 100644 --- a/net/batman-adv/hard-interface.c +++ b/net/batman-adv/hard-interface.c @@ -236,8 +236,8 @@ static void batadv_primary_if_select(struct batadv_priv *bat_priv, ASSERT_RTNL(); - if (new_hard_iface && !kref_get_unless_zero(&new_hard_iface->refcount)) - new_hard_iface = NULL; + if (new_hard_iface) + kref_get(&new_hard_iface->refcount); curr_hard_iface = rcu_dereference_protected(bat_priv->primary_if, 1); rcu_assign_pointer(bat_priv->primary_if, new_hard_iface); @@ -467,8 +467,7 @@ int batadv_hardif_enable_interface(struct batadv_hard_iface *hard_iface, if (hard_iface->if_status != BATADV_IF_NOT_IN_USE) goto out; - if (!kref_get_unless_zero(&hard_iface->refcount)) - goto out; + kref_get(&hard_iface->refcount); soft_iface = dev_get_by_name(net, iface_name); diff --git a/net/batman-adv/originator.c b/net/batman-adv/originator.c index 2ed2cc89a669..04fa139911c3 100644 --- a/net/batman-adv/originator.c +++ b/net/batman-adv/originator.c @@ -374,12 +374,8 @@ batadv_orig_ifinfo_new(struct batadv_orig_node *orig_node, if (!orig_ifinfo) goto out; - if (if_outgoing != BATADV_IF_DEFAULT && - !kref_get_unless_zero(&if_outgoing->refcount)) { - kfree(orig_ifinfo); - orig_ifinfo = NULL; - goto out; - } + if (if_outgoing != BATADV_IF_DEFAULT) + kref_get(&if_outgoing->refcount); reset_time = jiffies - 1; reset_time -= msecs_to_jiffies(BATADV_RESET_PROTECTION_MS); @@ -455,11 +451,8 @@ batadv_neigh_ifinfo_new(struct batadv_neigh_node *neigh, if (!neigh_ifinfo) goto out; - if (if_outgoing && !kref_get_unless_zero(&if_outgoing->refcount)) { - kfree(neigh_ifinfo); - neigh_ifinfo = NULL; - goto out; - } + if (if_outgoing) + kref_get(&if_outgoing->refcount); INIT_HLIST_NODE(&neigh_ifinfo->list); kref_init(&neigh_ifinfo->refcount); @@ -532,15 +525,11 @@ batadv_hardif_neigh_create(struct batadv_hard_iface *hard_iface, if (hard
[PATCH 17/17] batman-adv: use batadv_compare_eth when possible
When comparing Ethernet address it is better to use the more generic batadv_compare_eth. The latter is also optimised for architectures having a fast unaligned access. Signed-off-by: Antonio Quartulli [s...@narfation.org: fix conflicts with current version] Signed-off-by: Sven Eckelmann Signed-off-by: Marek Lindner --- net/batman-adv/network-coding.c | 6 ++ 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/net/batman-adv/network-coding.c b/net/batman-adv/network-coding.c index df5ae9c7e507..678f06865312 100644 --- a/net/batman-adv/network-coding.c +++ b/net/batman-adv/network-coding.c @@ -521,12 +521,10 @@ static bool batadv_nc_hash_compare(const struct hlist_node *node, nc_path2 = data2; /* Return 1 if the two keys are identical */ - if (memcmp(nc_path1->prev_hop, nc_path2->prev_hop, - sizeof(nc_path1->prev_hop)) != 0) + if (!batadv_compare_eth(nc_path1->prev_hop, nc_path2->prev_hop)) return false; - if (memcmp(nc_path1->next_hop, nc_path2->next_hop, - sizeof(nc_path1->next_hop)) != 0) + if (!batadv_compare_eth(nc_path1->next_hop, nc_path2->next_hop)) return false; return true; -- 2.8.2
[PATCH 16/17] batman-adv: replace ethertype variable with ETH_P_BATMAN for readability
From: Marek Lindner Signed-off-by: Marek Lindner Reviewed-by: Sven Eckelmann Signed-off-by: Antonio Quartulli --- net/batman-adv/soft-interface.c | 8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/net/batman-adv/soft-interface.c b/net/batman-adv/soft-interface.c index 3a0fc3c18444..343d2c904399 100644 --- a/net/batman-adv/soft-interface.c +++ b/net/batman-adv/soft-interface.c @@ -186,7 +186,6 @@ static int batadv_interface_tx(struct sk_buff *skb, struct batadv_priv *bat_priv = netdev_priv(soft_iface); struct batadv_hard_iface *primary_if = NULL; struct batadv_bcast_packet *bcast_packet; - __be16 ethertype = htons(ETH_P_BATMAN); static const u8 stp_addr[ETH_ALEN] = {0x01, 0x80, 0xC2, 0x00, 0x00, 0x00}; static const u8 ectp_addr[ETH_ALEN] = {0xCF, 0x00, 0x00, 0x00, @@ -216,7 +215,8 @@ static int batadv_interface_tx(struct sk_buff *skb, case ETH_P_8021Q: vhdr = vlan_eth_hdr(skb); - if (vhdr->h_vlan_encapsulated_proto != ethertype) { + /* drop batman-in-batman packets to prevent loops */ + if (vhdr->h_vlan_encapsulated_proto != htons(ETH_P_BATMAN)) { network_offset += VLAN_HLEN; break; } @@ -404,7 +404,6 @@ void batadv_interface_rx(struct net_device *soft_iface, { struct batadv_bcast_packet *batadv_bcast_packet; struct batadv_priv *bat_priv = netdev_priv(soft_iface); - __be16 ethertype = htons(ETH_P_BATMAN); struct vlan_ethhdr *vhdr; struct ethhdr *ethhdr; unsigned short vid; @@ -434,7 +433,8 @@ void batadv_interface_rx(struct net_device *soft_iface, vhdr = (struct vlan_ethhdr *)skb->data; - if (vhdr->h_vlan_encapsulated_proto != ethertype) + /* drop batman-in-batman packets to prevent loops */ + if (vhdr->h_vlan_encapsulated_proto != htons(ETH_P_BATMAN)) break; /* fall through */ -- 2.8.2
[PATCH 12/17] batman-adv: Use kref_get for batadv_gw_node_add
From: Sven Eckelmann batadv_gw_node_add requires that the caller already has a valid reference for orig_node. It is therefore not possible that it has an reference counter of 0 and was still given to this function The kref_get function instead WARNs (with debug information) when the reference counter would still be 0. This makes a bug in batman-adv better visible because kref_get_unless_zero would have ignored this problem. Signed-off-by: Sven Eckelmann Signed-off-by: Marek Lindner Signed-off-by: Antonio Quartulli --- net/batman-adv/gateway_client.c | 8 ++-- 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/net/batman-adv/gateway_client.c b/net/batman-adv/gateway_client.c index bb1c4f37716e..5839c569f769 100644 --- a/net/batman-adv/gateway_client.c +++ b/net/batman-adv/gateway_client.c @@ -440,15 +440,11 @@ static void batadv_gw_node_add(struct batadv_priv *bat_priv, if (gateway->bandwidth_down == 0) return; - if (!kref_get_unless_zero(&orig_node->refcount)) - return; - gw_node = kzalloc(sizeof(*gw_node), GFP_ATOMIC); - if (!gw_node) { - batadv_orig_node_put(orig_node); + if (!gw_node) return; - } + kref_get(&orig_node->refcount); INIT_HLIST_NODE(&gw_node->list); gw_node->orig_node = orig_node; gw_node->bandwidth_down = ntohl(gateway->bandwidth_down); -- 2.8.2
[PATCH 11/17] batman-adv: Use kref_get for batadv_gw_select
From: Sven Eckelmann batadv_gw_select requires that the caller already has a valid reference for new_gw_node. It is therefore not possible that it has an reference counter of 0 and was still given to this function The kref_get function instead WARNs (with debug information) when the reference counter would still be 0. This makes a bug in batman-adv better visible because kref_get_unless_zero would have ignored this problem. Signed-off-by: Sven Eckelmann Signed-off-by: Marek Lindner Signed-off-by: Antonio Quartulli --- net/batman-adv/gateway_client.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/batman-adv/gateway_client.c b/net/batman-adv/gateway_client.c index c59aff5ccac8..bb1c4f37716e 100644 --- a/net/batman-adv/gateway_client.c +++ b/net/batman-adv/gateway_client.c @@ -135,8 +135,8 @@ static void batadv_gw_select(struct batadv_priv *bat_priv, spin_lock_bh(&bat_priv->gw.list_lock); - if (new_gw_node && !kref_get_unless_zero(&new_gw_node->refcount)) - new_gw_node = NULL; + if (new_gw_node) + kref_get(&new_gw_node->refcount); curr_gw_node = rcu_dereference_protected(bat_priv->gw.curr_gw, 1); rcu_assign_pointer(bat_priv->gw.curr_gw, new_gw_node); -- 2.8.2
[PATCH 05/17] batman-adv: add detection for complex bridge loops
From: Simon Wunderlich There are network setups where the current bridge loop avoidance can't detect bridge loops. The minimal setup affected would consist of two LANs and two separate meshes, connected in a ring like that: A...(mesh1)...B | | (LAN1)(LAN2) | | C...(mesh2)...D Since both the meshes and backbones are separate, the bridge loop avoidance has not enough information to detect and avoid the loop in this case. Even if these scenarios can't be fixed easily, these kind of loops can be detected. This patch implements a periodic check (running every 60 seconds for now) which sends a broadcast frame with a random MAC address on each backbone VLAN. If a broadcast frame with the same MAC address is received shortly after on the mesh, we know that there must be a loop and report that incident as well as throw an uevent to let others handle that problem. Signed-off-by: Simon Wunderlich [s...@narfation.org: fix conflicts with current version] Signed-off-by: Sven Eckelmann Signed-off-by: Marek Lindner Signed-off-by: Antonio Quartulli --- net/batman-adv/bridge_loop_avoidance.c | 139 + net/batman-adv/main.h | 4 + net/batman-adv/packet.h| 1 + net/batman-adv/sysfs.c | 6 +- net/batman-adv/types.h | 8 ++ 5 files changed, 156 insertions(+), 2 deletions(-) diff --git a/net/batman-adv/bridge_loop_avoidance.c b/net/batman-adv/bridge_loop_avoidance.c index 2c9aa671a49b..5064ae5e9b34 100644 --- a/net/batman-adv/bridge_loop_avoidance.c +++ b/net/batman-adv/bridge_loop_avoidance.c @@ -50,6 +50,7 @@ #include "hash.h" #include "originator.h" #include "packet.h" +#include "sysfs.h" #include "translation-table.h" static const u8 batadv_announce_mac[4] = {0x43, 0x05, 0x43, 0x05}; @@ -407,6 +408,14 @@ static void batadv_bla_send_claim(struct batadv_priv *bat_priv, u8 *mac, ethhdr->h_source, ethhdr->h_dest, BATADV_PRINT_VID(vid)); break; + case BATADV_CLAIM_TYPE_LOOPDETECT: + ether_addr_copy(ethhdr->h_source, mac); + batadv_dbg(BATADV_DBG_BLA, bat_priv, + "bla_send_claim(): LOOPDETECT of %pM to %pM on vid %d\n", + ethhdr->h_source, ethhdr->h_dest, + BATADV_PRINT_VID(vid)); + + break; } if (vid & BATADV_VLAN_HAS_TAG) @@ -427,6 +436,36 @@ out: } /** + * batadv_bla_loopdetect_report - worker for reporting the loop + * @work: work queue item + * + * Throws an uevent, as the loopdetect check function can't do that itself + * since the kernel may sleep while throwing uevents. + */ +static void batadv_bla_loopdetect_report(struct work_struct *work) +{ + struct batadv_bla_backbone_gw *backbone_gw; + struct batadv_priv *bat_priv; + char vid_str[6] = { '\0' }; + + backbone_gw = container_of(work, struct batadv_bla_backbone_gw, + report_work); + bat_priv = backbone_gw->bat_priv; + + batadv_info(bat_priv->soft_iface, + "Possible loop on VLAN %d detected which can't be handled by BLA - please check your network setup!\n", + BATADV_PRINT_VID(backbone_gw->vid)); + snprintf(vid_str, sizeof(vid_str), "%d", +BATADV_PRINT_VID(backbone_gw->vid)); + vid_str[sizeof(vid_str) - 1] = 0; + + batadv_throw_uevent(bat_priv, BATADV_UEV_BLA, BATADV_UEV_LOOPDETECT, + vid_str); + + batadv_backbone_gw_put(backbone_gw); +} + +/** * batadv_bla_get_backbone_gw - finds or creates a backbone gateway * @bat_priv: the bat priv with all the soft interface information * @orig: the mac address of the originator @@ -464,6 +503,7 @@ batadv_bla_get_backbone_gw(struct batadv_priv *bat_priv, u8 *orig, atomic_set(&entry->request_sent, 0); atomic_set(&entry->wait_periods, 0); ether_addr_copy(entry->orig, orig); + INIT_WORK(&entry->report_work, batadv_bla_loopdetect_report); /* one for the hash, one for returning */ kref_init(&entry->refcount); @@ -1060,6 +1100,10 @@ static int batadv_bla_process_claim(struct batadv_priv *bat_priv, if (vlan_depth > 1) return 1; + /* Let the loopdetect frames on the mesh in any case. */ + if (bla_dst->type == BATADV_CLAIM_TYPE_LOOPDETECT) + return 0; + /* check if it is a claim frame. */ ret = batadv_check_claim_group(bat_priv, primary_if, hw_src, hw_dst, ethhdr); @@ -1265,6 +1309,26 @@ void batadv_bla_update_orig_address(struct batadv_priv *bat_priv, }
[PATCH 06/17] batman-adv: Check hard_iface refcnt before calling function
From: Sven Eckelmann The batadv_hardif_list list is checked in many situations and the items in this list are given to specialized functions to modify the routing behavior. At the moment each of these called functions has to check itself whether the received batadv_hard_iface has a refcount > 0 before it can increase the reference counter and use it in other objects. This can easily lead to problems because it is not easily visible where all callers of a function got the batadv_hard_iface object from and whether they already hold a valid reference. Checking the reference counter directly before calling a subfunction with a pointer from the batadv_hardif_list avoids this problem. Signed-off-by: Sven Eckelmann Signed-off-by: Marek Lindner Signed-off-by: Antonio Quartulli --- net/batman-adv/bat_iv_ogm.c | 11 +++ net/batman-adv/bat_v_ogm.c | 14 +- net/batman-adv/originator.c | 5 + net/batman-adv/send.c | 6 ++ 4 files changed, 35 insertions(+), 1 deletion(-) diff --git a/net/batman-adv/bat_iv_ogm.c b/net/batman-adv/bat_iv_ogm.c index 8c1710bba803..57e9962c7090 100644 --- a/net/batman-adv/bat_iv_ogm.c +++ b/net/batman-adv/bat_iv_ogm.c @@ -987,9 +987,15 @@ static void batadv_iv_ogm_schedule(struct batadv_hard_iface *hard_iface) list_for_each_entry_rcu(tmp_hard_iface, &batadv_hardif_list, list) { if (tmp_hard_iface->soft_iface != hard_iface->soft_iface) continue; + + if (!kref_get_unless_zero(&tmp_hard_iface->refcount)) + continue; + batadv_iv_ogm_queue_add(bat_priv, *ogm_buff, *ogm_buff_len, hard_iface, tmp_hard_iface, 1, send_time); + + batadv_hardif_put(tmp_hard_iface); } rcu_read_unlock(); @@ -1767,8 +1773,13 @@ static void batadv_iv_ogm_process(const struct sk_buff *skb, int ogm_offset, if (hard_iface->soft_iface != bat_priv->soft_iface) continue; + if (!kref_get_unless_zero(&hard_iface->refcount)) + continue; + batadv_iv_ogm_process_per_outif(skb, ogm_offset, orig_node, if_incoming, hard_iface); + + batadv_hardif_put(hard_iface); } rcu_read_unlock(); diff --git a/net/batman-adv/bat_v_ogm.c b/net/batman-adv/bat_v_ogm.c index 4155fa57cf6d..473ebb9a0e73 100644 --- a/net/batman-adv/bat_v_ogm.c +++ b/net/batman-adv/bat_v_ogm.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -176,6 +177,9 @@ static void batadv_v_ogm_send(struct work_struct *work) if (hard_iface->soft_iface != bat_priv->soft_iface) continue; + if (!kref_get_unless_zero(&hard_iface->refcount)) + continue; + batadv_dbg(BATADV_DBG_BATMAN, bat_priv, "Sending own OGM2 packet (originator %pM, seqno %u, throughput %u, TTL %d) on interface %s [%pM]\n", ogm_packet->orig, ntohl(ogm_packet->seqno), @@ -185,10 +189,13 @@ static void batadv_v_ogm_send(struct work_struct *work) /* this skb gets consumed by batadv_v_ogm_send_to_if() */ skb_tmp = skb_clone(skb, GFP_ATOMIC); - if (!skb_tmp) + if (!skb_tmp) { + batadv_hardif_put(hard_iface); break; + } batadv_v_ogm_send_to_if(skb_tmp, hard_iface); + batadv_hardif_put(hard_iface); } rcu_read_unlock(); @@ -704,9 +711,14 @@ static void batadv_v_ogm_process(const struct sk_buff *skb, int ogm_offset, if (hard_iface->soft_iface != bat_priv->soft_iface) continue; + if (!kref_get_unless_zero(&hard_iface->refcount)) + continue; + batadv_v_ogm_process_per_outif(bat_priv, ethhdr, ogm_packet, orig_node, neigh_node, if_incoming, hard_iface); + + batadv_hardif_put(hard_iface); } rcu_read_unlock(); out: diff --git a/net/batman-adv/originator.c b/net/batman-adv/originator.c index f885a41d06d5..2ed2cc89a669 100644 --- a/net/batman-adv/originator.c +++ b/net/batman-adv/originator.c @@ -1160,6 +1160,9 @@ static bool batadv_purge_orig_node(struct batadv_priv *bat_priv, if (hard_iface->soft_iface != bat_priv->soft_iface) continue; + if (!kref_get_unless_zero(&hard_iface->refcount)) + continue; + best_neigh_node = batadv_find_best_
[PATCH 07/17] batman-adv: Check hard_iface refcnt when receiving skb
From: Sven Eckelmann The receive function may start processing an incoming packet while the hard_iface is shut down in a different context. All called functions called with the batadv_hard_iface object belonging to the incoming interface would have to check whether the reference counter is still > 0. This is rather error-prone because this check can be forgotten easily. Instead check the reference counter when receiving the object to make sure that all called functions have a valid reference. Signed-off-by: Sven Eckelmann Signed-off-by: Marek Lindner Signed-off-by: Antonio Quartulli --- net/batman-adv/main.c | 14 +- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/net/batman-adv/main.c b/net/batman-adv/main.c index 78c05a91ae6f..c8d8bc78a518 100644 --- a/net/batman-adv/main.c +++ b/net/batman-adv/main.c @@ -401,11 +401,19 @@ int batadv_batman_skb_recv(struct sk_buff *skb, struct net_device *dev, hard_iface = container_of(ptype, struct batadv_hard_iface, batman_adv_ptype); + + /* Prevent processing a packet received on an interface which is getting +* shut down otherwise the packet may trigger de-reference errors +* further down in the receive path. +*/ + if (!kref_get_unless_zero(&hard_iface->refcount)) + goto err_out; + skb = skb_share_check(skb, GFP_ATOMIC); /* skb was released by skb_share_check() */ if (!skb) - goto err_out; + goto err_put; /* packet should hold at least type and version */ if (unlikely(!pskb_may_pull(skb, 2))) @@ -448,6 +456,8 @@ int batadv_batman_skb_recv(struct sk_buff *skb, struct net_device *dev, if (ret == NET_RX_DROP) kfree_skb(skb); + batadv_hardif_put(hard_iface); + /* return NET_RX_SUCCESS in any case as we * most probably dropped the packet for * routing-logical reasons. @@ -456,6 +466,8 @@ int batadv_batman_skb_recv(struct sk_buff *skb, struct net_device *dev, err_free: kfree_skb(skb); +err_put: + batadv_hardif_put(hard_iface); err_out: return NET_RX_DROP; } -- 2.8.2
[PATCH 04/17] batman-adv: Create batman soft interfaces within correct netns.
From: Andrew Lunn When creating a soft interface, create it in the same netns as the hard interface. Replace all references to init_net with the correct name space for the interface being manipulated. Suggested-by: Daniel Ehlers Signed-off-by: Andrew Lunn Acked-by: Antonio Quartulli Signed-off-by: Sven Eckelmann Signed-off-by: Marek Lindner Signed-off-by: Antonio Quartulli --- net/batman-adv/hard-interface.c| 10 +- net/batman-adv/hard-interface.h| 3 ++- net/batman-adv/soft-interface.c| 7 +-- net/batman-adv/soft-interface.h| 3 ++- net/batman-adv/sysfs.c | 3 ++- net/batman-adv/translation-table.c | 4 ++-- 6 files changed, 18 insertions(+), 12 deletions(-) diff --git a/net/batman-adv/hard-interface.c b/net/batman-adv/hard-interface.c index 0a7deaf2670a..f0e1899e5b6b 100644 --- a/net/batman-adv/hard-interface.c +++ b/net/batman-adv/hard-interface.c @@ -36,7 +36,6 @@ #include #include #include -#include #include "bridge_loop_avoidance.h" #include "debugfs.h" @@ -121,6 +120,7 @@ static bool batadv_mutual_parents(const struct net_device *dev1, static bool batadv_is_on_batman_iface(const struct net_device *net_dev) { struct net_device *parent_dev; + struct net *net = dev_net(net_dev); bool ret; /* check if this is a batman-adv mesh interface */ @@ -133,7 +133,7 @@ static bool batadv_is_on_batman_iface(const struct net_device *net_dev) return false; /* recurse over the parent device */ - parent_dev = __dev_get_by_index(&init_net, dev_get_iflink(net_dev)); + parent_dev = __dev_get_by_index(net, dev_get_iflink(net_dev)); /* if we got a NULL parent_dev there is something broken.. */ if (WARN(!parent_dev, "Cannot find parent device")) return false; @@ -456,7 +456,7 @@ static int batadv_master_del_slave(struct batadv_hard_iface *slave, } int batadv_hardif_enable_interface(struct batadv_hard_iface *hard_iface, - const char *iface_name) + struct net *net, const char *iface_name) { struct batadv_priv *bat_priv; struct net_device *soft_iface, *master; @@ -470,10 +470,10 @@ int batadv_hardif_enable_interface(struct batadv_hard_iface *hard_iface, if (!kref_get_unless_zero(&hard_iface->refcount)) goto out; - soft_iface = dev_get_by_name(&init_net, iface_name); + soft_iface = dev_get_by_name(net, iface_name); if (!soft_iface) { - soft_iface = batadv_softif_create(iface_name); + soft_iface = batadv_softif_create(net, iface_name); if (!soft_iface) { ret = -ENOMEM; diff --git a/net/batman-adv/hard-interface.h b/net/batman-adv/hard-interface.h index d74f1983f33e..a76724d369bf 100644 --- a/net/batman-adv/hard-interface.h +++ b/net/batman-adv/hard-interface.h @@ -28,6 +28,7 @@ #include struct net_device; +struct net; enum batadv_hard_if_state { BATADV_IF_NOT_IN_USE, @@ -55,7 +56,7 @@ bool batadv_is_wifi_iface(int ifindex); struct batadv_hard_iface* batadv_hardif_get_by_netdev(const struct net_device *net_dev); int batadv_hardif_enable_interface(struct batadv_hard_iface *hard_iface, - const char *iface_name); + struct net *net, const char *iface_name); void batadv_hardif_disable_interface(struct batadv_hard_iface *hard_iface, enum batadv_hard_if_cleanup autodel); void batadv_hardif_remove_interfaces(void); diff --git a/net/batman-adv/soft-interface.c b/net/batman-adv/soft-interface.c index 66dd0aac480a..04866c9b860a 100644 --- a/net/batman-adv/soft-interface.c +++ b/net/batman-adv/soft-interface.c @@ -885,13 +885,14 @@ static int batadv_softif_slave_add(struct net_device *dev, struct net_device *slave_dev) { struct batadv_hard_iface *hard_iface; + struct net *net = dev_net(dev); int ret = -EINVAL; hard_iface = batadv_hardif_get_by_netdev(slave_dev); if (!hard_iface || hard_iface->soft_iface) goto out; - ret = batadv_hardif_enable_interface(hard_iface, dev->name); + ret = batadv_hardif_enable_interface(hard_iface, net, dev->name); out: if (hard_iface) @@ -988,7 +989,7 @@ static void batadv_softif_init_early(struct net_device *dev) memset(priv, 0, sizeof(*priv)); } -struct net_device *batadv_softif_create(const char *name) +struct net_device *batadv_softif_create(struct net *net, const char *name) { struct net_device *soft_iface; int ret; @@ -998,6 +999,8 @@ struct net_device *batadv_softif_create(const char *name) if (!soft_iface) return NULL; + dev_net_set(soft_iface, net); + soft_
[PATCH 09/17] batman-adv: Use kref_get for batadv_tvlv_container_get
From: Sven Eckelmann batadv_tvlv_container_get requires that tvlv.container_list_lock is held by the caller. It is therefore not possible that an item in tvlv.container_list has an reference counter of 0 and is still in the list The kref_get function instead WARNs (with debug information) when the reference counter would still be 0. This makes a bug in batman-adv better visible because kref_get_unless_zero would have ignored this problem. Signed-off-by: Sven Eckelmann Signed-off-by: Marek Lindner Signed-off-by: Antonio Quartulli --- net/batman-adv/main.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/net/batman-adv/main.c b/net/batman-adv/main.c index c8d8bc78a518..5f2974bd1227 100644 --- a/net/batman-adv/main.c +++ b/net/batman-adv/main.c @@ -748,9 +748,7 @@ batadv_tvlv_container_get(struct batadv_priv *bat_priv, u8 type, u8 version) if (tvlv_tmp->tvlv_hdr.version != version) continue; - if (!kref_get_unless_zero(&tvlv_tmp->refcount)) - continue; - + kref_get(&tvlv_tmp->refcount); tvlv = tvlv_tmp; break; } -- 2.8.2
[PATCH 02/17] batman-adv: Remove hdr_size skb size check in batadv_interface_rx
From: Sven Eckelmann The callers of batadv_interface_rx have to make sure that enough data can be pulled from the skb when they read the batman-adv header. The only two functions using it are either calling pskb_may_pull with hdr_size directly (batadv_recv_bcast_packet) or indirectly via batadv_check_unicast_packet (batadv_recv_unicast_packet). Reported-by: Marek Lindner Signed-off-by: Sven Eckelmann Signed-off-by: Marek Lindner Signed-off-by: Antonio Quartulli --- net/batman-adv/soft-interface.c | 4 1 file changed, 4 deletions(-) diff --git a/net/batman-adv/soft-interface.c b/net/batman-adv/soft-interface.c index dc9a61a5122d..d72f88707736 100644 --- a/net/batman-adv/soft-interface.c +++ b/net/batman-adv/soft-interface.c @@ -413,10 +413,6 @@ void batadv_interface_rx(struct net_device *soft_iface, batadv_bcast_packet = (struct batadv_bcast_packet *)skb->data; is_bcast = (batadv_bcast_packet->packet_type == BATADV_BCAST); - /* check if enough space is available for pulling, and pull */ - if (!pskb_may_pull(skb, hdr_size)) - goto dropped; - skb_pull_rcsum(skb, hdr_size); skb_reset_mac_header(skb); -- 2.8.2
[PATCH 08/17] batman-adv: Increase hard_iface refcnt for ptype
From: Sven Eckelmann The hard_iface is referenced in the packet_type for batman-adv. Increase the refcounter of the hard_interface for it to have an explicit reference for it in case this functionality gets refactorted and the currently used implicit reference for it will be removed. Signed-off-by: Sven Eckelmann Signed-off-by: Marek Lindner Signed-off-by: Antonio Quartulli --- net/batman-adv/hard-interface.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/net/batman-adv/hard-interface.c b/net/batman-adv/hard-interface.c index f0e1899e5b6b..d3d37f3f99cf 100644 --- a/net/batman-adv/hard-interface.c +++ b/net/batman-adv/hard-interface.c @@ -522,6 +522,7 @@ int batadv_hardif_enable_interface(struct batadv_hard_iface *hard_iface, goto err_upper; } + kref_get(&hard_iface->refcount); hard_iface->batman_adv_ptype.type = ethertype; hard_iface->batman_adv_ptype.func = batadv_batman_skb_recv; hard_iface->batman_adv_ptype.dev = hard_iface->net_dev; @@ -583,6 +584,7 @@ void batadv_hardif_disable_interface(struct batadv_hard_iface *hard_iface, batadv_info(hard_iface->soft_iface, "Removing interface: %s\n", hard_iface->net_dev->name); dev_remove_pack(&hard_iface->batman_adv_ptype); + batadv_hardif_put(hard_iface); bat_priv->num_ifaces--; batadv_orig_hash_del_if(hard_iface, bat_priv->num_ifaces); -- 2.8.2
[PATCH 03/17] batman-adv: NETIF_F_NETNS_LOCAL feature to prevent netns moves
From: Andrew Lunn The batX soft interface should not be moved between network name spaces. This is similar to bridges, bonds, tunnels, which are not allowed to move between network namespaces. Suggested-by: Daniel Ehlers Signed-off-by: Andrew Lunn Acked-by: Antonio Quartulli Reviewed-by: Sven Eckelmann Signed-off-by: Marek Lindner Signed-off-by: Antonio Quartulli --- net/batman-adv/soft-interface.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/batman-adv/soft-interface.c b/net/batman-adv/soft-interface.c index d72f88707736..66dd0aac480a 100644 --- a/net/batman-adv/soft-interface.c +++ b/net/batman-adv/soft-interface.c @@ -972,7 +972,7 @@ static void batadv_softif_init_early(struct net_device *dev) dev->netdev_ops = &batadv_netdev_ops; dev->destructor = batadv_softif_free; - dev->features |= NETIF_F_HW_VLAN_CTAG_FILTER; + dev->features |= NETIF_F_HW_VLAN_CTAG_FILTER | NETIF_F_NETNS_LOCAL; dev->priv_flags |= IFF_NO_QUEUE; /* can't call min_mtu, because the needed variables -- 2.8.2
[PATCH 01/17] batman-adv: Remove unused parameter recv_if of batadv_interface_rx
From: Sven Eckelmann Signed-off-by: Sven Eckelmann Signed-off-by: Marek Lindner Signed-off-by: Antonio Quartulli --- net/batman-adv/routing.c| 5 ++--- net/batman-adv/soft-interface.c | 5 ++--- net/batman-adv/soft-interface.h | 4 ++-- 3 files changed, 6 insertions(+), 8 deletions(-) diff --git a/net/batman-adv/routing.c b/net/batman-adv/routing.c index b781bf753250..2ecfca246be4 100644 --- a/net/batman-adv/routing.c +++ b/net/batman-adv/routing.c @@ -912,7 +912,7 @@ int batadv_recv_unicast_packet(struct sk_buff *skb, hdr_size)) goto rx_success; - batadv_interface_rx(recv_if->soft_iface, skb, recv_if, hdr_size, + batadv_interface_rx(recv_if->soft_iface, skb, hdr_size, orig_node); rx_success: @@ -1122,8 +1122,7 @@ int batadv_recv_bcast_packet(struct sk_buff *skb, goto rx_success; /* broadcast for me */ - batadv_interface_rx(recv_if->soft_iface, skb, recv_if, hdr_size, - orig_node); + batadv_interface_rx(recv_if->soft_iface, skb, hdr_size, orig_node); rx_success: ret = NET_RX_SUCCESS; diff --git a/net/batman-adv/soft-interface.c b/net/batman-adv/soft-interface.c index dfb4d56120b6..dc9a61a5122d 100644 --- a/net/batman-adv/soft-interface.c +++ b/net/batman-adv/soft-interface.c @@ -385,7 +385,6 @@ end: * batadv_interface_rx - receive ethernet frame on local batman-adv interface * @soft_iface: local interface which will receive the ethernet frame * @skb: ethernet frame for @soft_iface - * @recv_if: interface on which the batman-adv packet was received * @hdr_size: size of already parsed batman-adv header * @orig_node: originator from which the batman-adv packet was sent * @@ -400,8 +399,8 @@ end: * isolated clients. */ void batadv_interface_rx(struct net_device *soft_iface, -struct sk_buff *skb, struct batadv_hard_iface *recv_if, -int hdr_size, struct batadv_orig_node *orig_node) +struct sk_buff *skb, int hdr_size, +struct batadv_orig_node *orig_node) { struct batadv_bcast_packet *batadv_bcast_packet; struct batadv_priv *bat_priv = netdev_priv(soft_iface); diff --git a/net/batman-adv/soft-interface.h b/net/batman-adv/soft-interface.h index 9ae265703d23..5942da3d03d5 100644 --- a/net/batman-adv/soft-interface.h +++ b/net/batman-adv/soft-interface.h @@ -27,8 +27,8 @@ struct sk_buff; int batadv_skb_head_push(struct sk_buff *skb, unsigned int len); void batadv_interface_rx(struct net_device *soft_iface, -struct sk_buff *skb, struct batadv_hard_iface *recv_if, -int hdr_size, struct batadv_orig_node *orig_node); +struct sk_buff *skb, int hdr_size, +struct batadv_orig_node *orig_node); struct net_device *batadv_softif_create(const char *name); void batadv_softif_destroy_sysfs(struct net_device *soft_iface); int batadv_softif_is_valid(const struct net_device *net_dev); -- 2.8.2
pull request: batman-adv 20160511
Hi David, here you have a pull request intended for net-next. There are 17 patches in this batch, but most of them are cleanups and minor code re-arrangement. The more detailed description follows in the git tag. Please pull or let me know of any problem. Thanks a lot, Antonio The following changes since commit c047c3b1af6214b447e353527e394fa3f3e86397: netfilter: conntrack: remove uninitialized shadow variable (2016-05-10 01:04:04 -0400) are available in the git repository at: git://git.open-mesh.org/linux-merge.git tags/batman-adv-for-davem for you to fetch changes up to 676970e55b1033af7f0a03d4037b4d9b76327ded: batman-adv: use batadv_compare_eth when possible (2016-05-10 18:28:54 +0800) Included changes: - remove useless skb size check in batadv_interface_rx - basic netns support introduced by Andrew Lunn: - prevent virtual interface from changing netns by setting NETIF_F_NETNS_LOCAL - create virtual interface within the netns of the first hard-interface - introduce detection of complex bridge loops and report event to the user (via udev) when the Bridge Loop Avoidance mechanism can't prevent them - minor reference counting bugfixes for the hard_iface object that couldn't make it via the net tree - use kref_get() instead of kref_get_unless_zero() to make reference counting bug more visible - use batadv_compare_eth() all over the code when possible instead of plain memcmp() - minor code cleanup and style adjustments Andrew Lunn (2): batman-adv: NETIF_F_NETNS_LOCAL feature to prevent netns moves batman-adv: Create batman soft interfaces within correct netns. Antonio Quartulli (1): batman-adv: use batadv_compare_eth when possible Marek Lindner (1): batman-adv: replace ethertype variable with ETH_P_BATMAN for readability Simon Wunderlich (1): batman-adv: add detection for complex bridge loops Sven Eckelmann (12): batman-adv: Remove unused parameter recv_if of batadv_interface_rx batman-adv: Remove hdr_size skb size check in batadv_interface_rx batman-adv: Check hard_iface refcnt before calling function batman-adv: Check hard_iface refcnt when receiving skb batman-adv: Increase hard_iface refcnt for ptype batman-adv: Use kref_get for batadv_tvlv_container_get batman-adv: Use kref_get for batadv_nc_get_nc_node batman-adv: Use kref_get for batadv_gw_select batman-adv: Use kref_get for batadv_gw_node_add batman-adv: Use kref_get for hard_iface subfunctions batman-adv: Use kref_get for _batadv_update_route batman-adv: Use bool as return type for boolean functions net/batman-adv/bat_iv_ogm.c| 48 ++--- net/batman-adv/bat_v_ogm.c | 14 +- net/batman-adv/bitarray.c | 16 +- net/batman-adv/bitarray.h | 15 +- net/batman-adv/bridge_loop_avoidance.c | 314 - net/batman-adv/bridge_loop_avoidance.h | 43 ++--- net/batman-adv/debugfs.c | 2 +- net/batman-adv/distributed-arp-table.c | 6 +- net/batman-adv/gateway_client.c| 12 +- net/batman-adv/hard-interface.c| 34 ++-- net/batman-adv/hard-interface.h| 3 +- net/batman-adv/hash.h | 6 +- net/batman-adv/main.c | 18 +- net/batman-adv/main.h | 6 +- net/batman-adv/network-coding.c| 25 +-- net/batman-adv/originator.c| 39 ++-- net/batman-adv/originator.h| 2 +- net/batman-adv/packet.h| 1 + net/batman-adv/routing.c | 50 +++--- net/batman-adv/routing.h | 6 +- net/batman-adv/send.c | 6 + net/batman-adv/soft-interface.c| 32 ++-- net/batman-adv/soft-interface.h| 10 +- net/batman-adv/sysfs.c | 9 +- net/batman-adv/translation-table.c | 35 ++-- net/batman-adv/types.h | 8 + 26 files changed, 465 insertions(+), 295 deletions(-)
Re: pull request [net]: batman-adv 20160430
On Wed, May 04, 2016 at 02:13:50PM -0400, David Miller wrote: > > Just FYI I did this last night. Thanks a lot for letting me know David. Cheers, -- Antonio Quartulli signature.asc Description: Digital signature
Re: [PATCH net-next 4/5] treewide: replace dev->trans_start update with helper
On Tue, May 03, 2016 at 04:33:13PM +0200, Florian Westphal wrote: > Replace all trans_start updates with netif_trans_update helper. > change was done via spatch: > > struct net_device *d; > @@ > - d->trans_start = jiffies > + netif_trans_update(d) > > Compile tested only. > > Cc: user-mode-linux-de...@lists.sourceforge.net > Cc: linux-xte...@linux-xtensa.org > Cc: linux1394-de...@lists.sourceforge.net > Cc: linux-r...@vger.kernel.org > Cc: netdev@vger.kernel.org > Cc: mpt-fusionlinux@broadcom.com > Cc: linux-s...@vger.kernel.org > Cc: linux-...@vger.kernel.org > Cc: linux-par...@vger.kernel.org > Cc: linux-o...@vger.kernel.org > Cc: linux-h...@vger.kernel.org > Cc: linux-...@vger.kernel.org > Cc: linux-wirel...@vger.kernel.org > Cc: linux-s...@vger.kernel.org > Cc: de...@driverdev.osuosl.org > Cc: b.a.t.m@lists.open-mesh.org > Cc: linux-blueto...@vger.kernel.org > Signed-off-by: Florian Westphal > --- [...] > net/batman-adv/soft-interface.c| 2 +- [...] > diff --git a/net/batman-adv/soft-interface.c b/net/batman-adv/soft-interface.c > index 0710379..bae1397 100644 > --- a/net/batman-adv/soft-interface.c > +++ b/net/batman-adv/soft-interface.c > @@ -208,7 +208,7 @@ static int batadv_interface_tx(struct sk_buff *skb, > if (atomic_read(&bat_priv->mesh_state) != BATADV_MESH_ACTIVE) > goto dropped; > > - soft_iface->trans_start = jiffies; > + netif_trans_update(soft_iface); > vid = batadv_get_vid(skb, 0); > ethhdr = eth_hdr(skb); > Acked-by: Antonio Quartulli -- Antonio Quartulli signature.asc Description: Digital signature
[PATCH 14/15] batman-adv: Merge batadv_v_ogm_orig_update into batadv_v_ogm_route_update
From: Simon Wunderlich Since batadv_v_ogm_orig_update() was only called from one place and the calling function became very short, merge these two functions together. This should also reflect the protocol description of B.A.T.M.A.N. V better. Signed-off-by: Simon Wunderlich Signed-off-by: Marek Lindner Signed-off-by: Antonio Quartulli --- net/batman-adv/bat_v_ogm.c | 117 ++--- 1 file changed, 46 insertions(+), 71 deletions(-) diff --git a/net/batman-adv/bat_v_ogm.c b/net/batman-adv/bat_v_ogm.c index 07c999734fba..4155fa57cf6d 100644 --- a/net/batman-adv/bat_v_ogm.c +++ b/net/batman-adv/bat_v_ogm.c @@ -234,73 +234,6 @@ void batadv_v_ogm_primary_iface_set(struct batadv_hard_iface *primary_iface) } /** - * batadv_v_ogm_orig_update - update the originator status based on the received - * OGM - * @bat_priv: the bat priv with all the soft interface information - * @orig_node: the originator to update - * @neigh_node: the neighbour the OGM has been received from (to update) - * @ogm2: the received OGM - * @if_outgoing: the interface where this OGM is going to be forwarded through - */ -static void -batadv_v_ogm_orig_update(struct batadv_priv *bat_priv, -struct batadv_orig_node *orig_node, -struct batadv_neigh_node *neigh_node, -const struct batadv_ogm2_packet *ogm2, -struct batadv_hard_iface *if_outgoing) -{ - struct batadv_neigh_ifinfo *router_ifinfo = NULL, *neigh_ifinfo = NULL; - struct batadv_neigh_node *router = NULL; - s32 neigh_seq_diff; - u32 neigh_last_seqno; - u32 router_last_seqno; - u32 router_throughput, neigh_throughput; - - batadv_dbg(BATADV_DBG_BATMAN, bat_priv, - "Searching and updating originator entry of received packet\n"); - - /* if this neighbor already is our next hop there is nothing -* to change -*/ - router = batadv_orig_router_get(orig_node, if_outgoing); - if (router == neigh_node) - goto out; - - /* don't consider neighbours with worse throughput. -* also switch route if this seqno is BATADV_V_MAX_ORIGDIFF newer than -* the last received seqno from our best next hop. -*/ - if (router) { - router_ifinfo = batadv_neigh_ifinfo_get(router, if_outgoing); - neigh_ifinfo = batadv_neigh_ifinfo_get(neigh_node, if_outgoing); - - /* if these are not allocated, something is wrong. */ - if (!router_ifinfo || !neigh_ifinfo) - goto out; - - neigh_last_seqno = neigh_ifinfo->bat_v.last_seqno; - router_last_seqno = router_ifinfo->bat_v.last_seqno; - neigh_seq_diff = neigh_last_seqno - router_last_seqno; - router_throughput = router_ifinfo->bat_v.throughput; - neigh_throughput = neigh_ifinfo->bat_v.throughput; - - if ((neigh_seq_diff < BATADV_OGM_MAX_ORIGDIFF) && - (router_throughput >= neigh_throughput)) - goto out; - } - - batadv_update_route(bat_priv, orig_node, if_outgoing, neigh_node); - -out: - if (router_ifinfo) - batadv_neigh_ifinfo_put(router_ifinfo); - if (neigh_ifinfo) - batadv_neigh_ifinfo_put(neigh_ifinfo); - if (router) - batadv_neigh_node_put(router); -} - -/** * batadv_v_forward_penalty - apply a penalty to the throughput metric forwarded * with B.A.T.M.A.N. V OGMs * @bat_priv: the bat priv with all the soft interface information @@ -546,6 +479,11 @@ static bool batadv_v_ogm_route_update(struct batadv_priv *bat_priv, struct batadv_neigh_node *router = NULL; struct batadv_orig_node *orig_neigh_node = NULL; struct batadv_neigh_node *orig_neigh_router = NULL; + struct batadv_neigh_ifinfo *router_ifinfo = NULL, *neigh_ifinfo = NULL; + u32 router_throughput, neigh_throughput; + u32 router_last_seqno; + u32 neigh_last_seqno; + s32 neigh_seq_diff; bool forward = false; orig_neigh_node = batadv_v_ogm_orig_get(bat_priv, ethhdr->h_source); @@ -565,11 +503,44 @@ static bool batadv_v_ogm_route_update(struct batadv_priv *bat_priv, goto out; } - /* Update routes, and check if the OGM is from the best next hop */ - batadv_v_ogm_orig_update(bat_priv, orig_node, neigh_node, ogm2, -if_outgoing); - + /* Mark the OGM to be considered for forwarding, and update routes +* if needed. +*/ forward = true; + + batadv_dbg(BATADV_DBG_BATMAN, bat_priv, + "Searching and updating originator entry of received packet\n"); + + /* if this neighbor already is our next hop there is nothing +*
[PATCH 12/15] batman-adv: fix debuginfo macro style issue
From: Simon Wunderlich Structure initialization within the macros should follow the general coding style used in the kernel: put the initialization of the first variable and the closing brace on a separate line. Reported-by: Antonio Quartulli Signed-off-by: Simon Wunderlich [s...@narfation.org: fix conflicts with current version] Signed-off-by: Sven Eckelmann Signed-off-by: Marek Lindner Signed-off-by: Antonio Quartulli --- net/batman-adv/debugfs.c | 19 +++ 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/net/batman-adv/debugfs.c b/net/batman-adv/debugfs.c index 48253cf8341b..aa315da83429 100644 --- a/net/batman-adv/debugfs.c +++ b/net/batman-adv/debugfs.c @@ -365,14 +365,17 @@ static int batadv_nc_nodes_open(struct inode *inode, struct file *file) #define BATADV_DEBUGINFO(_name, _mode, _open) \ struct batadv_debuginfo batadv_debuginfo_##_name = { \ - .attr = { .name = __stringify(_name), \ - .mode = _mode, }, \ - .fops = { .owner = THIS_MODULE, \ - .open = _open,\ - .read = seq_read, \ - .llseek = seq_lseek, \ - .release = single_release,\ - } \ + .attr = { \ + .name = __stringify(_name), \ + .mode = _mode, \ + }, \ + .fops = { \ + .owner = THIS_MODULE, \ + .open = _open, \ + .read = seq_read, \ + .llseek = seq_lseek,\ + .release = single_release, \ + }, \ } /* the following attributes are general and therefore they will be directly -- 2.8.2
[PATCH 11/15] batman-adv: Fix function names on new line starting with '*'
From: Sven Eckelmann Some really long function names in batman-adv require a newline between return type and the function name. This has lead to some lines starting with *batadv_... This * belongs to the return type and thus should be on the same line as the return type. Signed-off-by: Sven Eckelmann Signed-off-by: Marek Lindner Signed-off-by: Antonio Quartulli --- net/batman-adv/bridge_loop_avoidance.c | 6 +++--- net/batman-adv/main.c | 8 net/batman-adv/network-coding.c| 18 +- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/net/batman-adv/bridge_loop_avoidance.c b/net/batman-adv/bridge_loop_avoidance.c index 60d33232bd10..2c9aa671a49b 100644 --- a/net/batman-adv/bridge_loop_avoidance.c +++ b/net/batman-adv/bridge_loop_avoidance.c @@ -200,9 +200,9 @@ static void batadv_claim_put(struct batadv_bla_claim *claim) * * Return: claim if found or NULL otherwise. */ -static struct batadv_bla_claim -*batadv_claim_hash_find(struct batadv_priv *bat_priv, - struct batadv_bla_claim *data) +static struct batadv_bla_claim * +batadv_claim_hash_find(struct batadv_priv *bat_priv, + struct batadv_bla_claim *data) { struct batadv_hashtable *hash = bat_priv->bla.claim_hash; struct hlist_head *head; diff --git a/net/batman-adv/main.c b/net/batman-adv/main.c index d64ddb961979..78c05a91ae6f 100644 --- a/net/batman-adv/main.c +++ b/net/batman-adv/main.c @@ -663,8 +663,8 @@ static void batadv_tvlv_handler_put(struct batadv_tvlv_handler *tvlv_handler) * * Return: tvlv handler if found or NULL otherwise. */ -static struct batadv_tvlv_handler -*batadv_tvlv_handler_get(struct batadv_priv *bat_priv, u8 type, u8 version) +static struct batadv_tvlv_handler * +batadv_tvlv_handler_get(struct batadv_priv *bat_priv, u8 type, u8 version) { struct batadv_tvlv_handler *tvlv_handler_tmp, *tvlv_handler = NULL; @@ -722,8 +722,8 @@ static void batadv_tvlv_container_put(struct batadv_tvlv_container *tvlv) * * Return: tvlv container if found or NULL otherwise. */ -static struct batadv_tvlv_container -*batadv_tvlv_container_get(struct batadv_priv *bat_priv, u8 type, u8 version) +static struct batadv_tvlv_container * +batadv_tvlv_container_get(struct batadv_priv *bat_priv, u8 type, u8 version) { struct batadv_tvlv_container *tvlv_tmp, *tvlv = NULL; diff --git a/net/batman-adv/network-coding.c b/net/batman-adv/network-coding.c index 0d3bf4368e9b..1da8e0e1b18f 100644 --- a/net/batman-adv/network-coding.c +++ b/net/batman-adv/network-coding.c @@ -793,10 +793,10 @@ static bool batadv_can_nc_with_orig(struct batadv_priv *bat_priv, * * Return: the nc_node if found, NULL otherwise. */ -static struct batadv_nc_node -*batadv_nc_find_nc_node(struct batadv_orig_node *orig_node, - struct batadv_orig_node *orig_neigh_node, - bool in_coding) +static struct batadv_nc_node * +batadv_nc_find_nc_node(struct batadv_orig_node *orig_node, + struct batadv_orig_node *orig_neigh_node, + bool in_coding) { struct batadv_nc_node *nc_node, *nc_node_out = NULL; struct list_head *list; @@ -835,11 +835,11 @@ static struct batadv_nc_node * * Return: the nc_node if found or created, NULL in case of an error. */ -static struct batadv_nc_node -*batadv_nc_get_nc_node(struct batadv_priv *bat_priv, - struct batadv_orig_node *orig_node, - struct batadv_orig_node *orig_neigh_node, - bool in_coding) +static struct batadv_nc_node * +batadv_nc_get_nc_node(struct batadv_priv *bat_priv, + struct batadv_orig_node *orig_node, + struct batadv_orig_node *orig_neigh_node, + bool in_coding) { struct batadv_nc_node *nc_node; spinlock_t *lock; /* Used to lock list selected by "int in_coding" */ -- 2.8.2
[PATCH 10/15] batman-adv: Add kernel-doc for batadv_interface_rx
From: Sven Eckelmann Signed-off-by: Sven Eckelmann Signed-off-by: Marek Lindner Signed-off-by: Antonio Quartulli --- net/batman-adv/soft-interface.c | 18 ++ 1 file changed, 18 insertions(+) diff --git a/net/batman-adv/soft-interface.c b/net/batman-adv/soft-interface.c index e158235ada06..d78c560852d7 100644 --- a/net/batman-adv/soft-interface.c +++ b/net/batman-adv/soft-interface.c @@ -381,6 +381,24 @@ end: return NETDEV_TX_OK; } +/** + * batadv_interface_rx - receive ethernet frame on local batman-adv interface + * @soft_iface: local interface which will receive the ethernet frame + * @skb: ethernet frame for @soft_iface + * @recv_if: interface on which the batman-adv packet was received + * @hdr_size: size of already parsed batman-adv header + * @orig_node: originator from which the batman-adv packet was sent + * + * Sends a ethernet frame to the receive path of the local @soft_iface. + * skb->data has still point to the batman-adv header with the size @hdr_size. + * The caller has to have parsed this header already and made sure that at least + * @hdr_size bytes are still available for pull in @skb. + * + * The packet may still get dropped. This can happen when the encapsulated + * ethernet frame is invalid or contains again an batman-adv packet. Also + * unicast packets will be dropped directly when it was sent between two + * isolated clients. + */ void batadv_interface_rx(struct net_device *soft_iface, struct sk_buff *skb, struct batadv_hard_iface *recv_if, int hdr_size, struct batadv_orig_node *orig_node) -- 2.8.2
[PATCH 13/15] batman-adv: move and restructure batadv_v_ogm_forward
From: Simon Wunderlich To match our code better to the protocol description of B.A.T.M.A.N. V, move batadv_v_ogm_forward() out into batadv_v_ogm_process_per_outif() and move all checks directly deciding whether the OGM should be forwarded into batadv_v_ogm_forward(). Signed-off-by: Simon Wunderlich Signed-off-by: Marek Lindner Signed-off-by: Antonio Quartulli --- net/batman-adv/bat_v_ogm.c | 110 ++--- 1 file changed, 63 insertions(+), 47 deletions(-) diff --git a/net/batman-adv/bat_v_ogm.c b/net/batman-adv/bat_v_ogm.c index d9bcbe6e7d65..07c999734fba 100644 --- a/net/batman-adv/bat_v_ogm.c +++ b/net/batman-adv/bat_v_ogm.c @@ -347,10 +347,12 @@ static u32 batadv_v_forward_penalty(struct batadv_priv *bat_priv, } /** - * batadv_v_ogm_forward - forward an OGM to the given outgoing interface + * batadv_v_ogm_forward - check conditions and forward an OGM to the given + * outgoing interface * @bat_priv: the bat priv with all the soft interface information * @ogm_received: previously received OGM to be forwarded - * @throughput: throughput to announce, may vary per outgoing interface + * @orig_node: the originator which has been updated + * @neigh_node: the neigh_node through with the OGM has been received * @if_incoming: the interface on which this OGM was received on * @if_outgoing: the interface to which the OGM has to be forwarded to * @@ -359,28 +361,57 @@ static u32 batadv_v_forward_penalty(struct batadv_priv *bat_priv, */ static void batadv_v_ogm_forward(struct batadv_priv *bat_priv, const struct batadv_ogm2_packet *ogm_received, -u32 throughput, +struct batadv_orig_node *orig_node, +struct batadv_neigh_node *neigh_node, struct batadv_hard_iface *if_incoming, struct batadv_hard_iface *if_outgoing) { + struct batadv_neigh_ifinfo *neigh_ifinfo = NULL; + struct batadv_orig_ifinfo *orig_ifinfo = NULL; + struct batadv_neigh_node *router = NULL; struct batadv_ogm2_packet *ogm_forward; unsigned char *skb_buff; struct sk_buff *skb; size_t packet_len; u16 tvlv_len; + /* only forward for specific interfaces, not for the default one. */ + if (if_outgoing == BATADV_IF_DEFAULT) + goto out; + + orig_ifinfo = batadv_orig_ifinfo_new(orig_node, if_outgoing); + if (!orig_ifinfo) + goto out; + + /* acquire possibly updated router */ + router = batadv_orig_router_get(orig_node, if_outgoing); + + /* strict rule: forward packets coming from the best next hop only */ + if (neigh_node != router) + goto out; + + /* don't forward the same seqno twice on one interface */ + if (orig_ifinfo->last_seqno_forwarded == ntohl(ogm_received->seqno)) + goto out; + + orig_ifinfo->last_seqno_forwarded = ntohl(ogm_received->seqno); + if (ogm_received->ttl <= 1) { batadv_dbg(BATADV_DBG_BATMAN, bat_priv, "ttl exceeded\n"); - return; + goto out; } + neigh_ifinfo = batadv_neigh_ifinfo_get(neigh_node, if_outgoing); + if (!neigh_ifinfo) + goto out; + tvlv_len = ntohs(ogm_received->tvlv_len); packet_len = BATADV_OGM2_HLEN + tvlv_len; skb = netdev_alloc_skb_ip_align(if_outgoing->net_dev, ETH_HLEN + packet_len); if (!skb) - return; + goto out; skb_reserve(skb, ETH_HLEN); skb_buff = skb_put(skb, packet_len); @@ -388,15 +419,23 @@ static void batadv_v_ogm_forward(struct batadv_priv *bat_priv, /* apply forward penalty */ ogm_forward = (struct batadv_ogm2_packet *)skb_buff; - ogm_forward->throughput = htonl(throughput); + ogm_forward->throughput = htonl(neigh_ifinfo->bat_v.throughput); ogm_forward->ttl--; batadv_dbg(BATADV_DBG_BATMAN, bat_priv, "Forwarding OGM2 packet on %s: throughput %u, ttl %u, received via %s\n", - if_outgoing->net_dev->name, throughput, ogm_forward->ttl, - if_incoming->net_dev->name); + if_outgoing->net_dev->name, ntohl(ogm_forward->throughput), + ogm_forward->ttl, if_incoming->net_dev->name); batadv_v_ogm_send_to_if(skb, if_outgoing); + +out: + if (orig_ifinfo) + batadv_orig_ifinfo_put(orig_ifinfo); + if (router) + batadv_neigh_node_put(router); + if (neigh_ifinfo) + batadv_neigh_ifinfo_put(neigh_ifinfo); } /** @@ -493,8 +532,10 @@ out: * @neigh_node: the neigh_node through with the OGM has
[PATCH 15/15] batman-adv: Split batadv_iv_ogm_orig_del_if function
From: Sven Eckelmann batadv_iv_ogm_orig_del_if handles two different buffers bcast_own and bcast_own_sum which should be resized. The error handling two for allocating these buffers causes the complexity of this function. This can be avoided completely when the function is split into a main function handling the locking, freeing and call of the subfunctions. The subfunction can then independently handle the resize of the buffers. This also allows to easily reuse the old buffer (which always is larger) in case a smaller buffer could not be allocated without increasing the code complexity. Signed-off-by: Sven Eckelmann Signed-off-by: Marek Lindner Signed-off-by: Antonio Quartulli --- net/batman-adv/bat_iv_ogm.c | 131 1 file changed, 84 insertions(+), 47 deletions(-) diff --git a/net/batman-adv/bat_iv_ogm.c b/net/batman-adv/bat_iv_ogm.c index 682fcaec56e6..8c1710bba803 100644 --- a/net/batman-adv/bat_iv_ogm.c +++ b/net/batman-adv/bat_iv_ogm.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include @@ -175,6 +176,79 @@ unlock: } /** + * batadv_iv_ogm_drop_bcast_own_entry - drop section of bcast_own + * @orig_node: the orig_node that has to be changed + * @max_if_num: the current amount of interfaces + * @del_if_num: the index of the interface being removed + */ +static void +batadv_iv_ogm_drop_bcast_own_entry(struct batadv_orig_node *orig_node, + int max_if_num, int del_if_num) +{ + size_t chunk_size; + size_t if_offset; + void *data_ptr; + + lockdep_assert_held(&orig_node->bat_iv.ogm_cnt_lock); + + chunk_size = sizeof(unsigned long) * BATADV_NUM_WORDS; + data_ptr = kmalloc_array(max_if_num, chunk_size, GFP_ATOMIC); + if (!data_ptr) + /* use old buffer when new one could not be allocated */ + data_ptr = orig_node->bat_iv.bcast_own; + + /* copy first part */ + memmove(data_ptr, orig_node->bat_iv.bcast_own, del_if_num * chunk_size); + + /* copy second part */ + if_offset = (del_if_num + 1) * chunk_size; + memmove((char *)data_ptr + del_if_num * chunk_size, + (uint8_t *)orig_node->bat_iv.bcast_own + if_offset, + (max_if_num - del_if_num) * chunk_size); + + /* bcast_own was shrunk down in new buffer; free old one */ + if (orig_node->bat_iv.bcast_own != data_ptr) { + kfree(orig_node->bat_iv.bcast_own); + orig_node->bat_iv.bcast_own = data_ptr; + } +} + +/** + * batadv_iv_ogm_drop_bcast_own_sum_entry - drop section of bcast_own_sum + * @orig_node: the orig_node that has to be changed + * @max_if_num: the current amount of interfaces + * @del_if_num: the index of the interface being removed + */ +static void +batadv_iv_ogm_drop_bcast_own_sum_entry(struct batadv_orig_node *orig_node, + int max_if_num, int del_if_num) +{ + size_t if_offset; + void *data_ptr; + + lockdep_assert_held(&orig_node->bat_iv.ogm_cnt_lock); + + data_ptr = kmalloc_array(max_if_num, sizeof(u8), GFP_ATOMIC); + if (!data_ptr) + /* use old buffer when new one could not be allocated */ + data_ptr = orig_node->bat_iv.bcast_own_sum; + + memmove(data_ptr, orig_node->bat_iv.bcast_own_sum, + del_if_num * sizeof(u8)); + + if_offset = (del_if_num + 1) * sizeof(u8); + memmove((char *)data_ptr + del_if_num * sizeof(u8), + orig_node->bat_iv.bcast_own_sum + if_offset, + (max_if_num - del_if_num) * sizeof(u8)); + + /* bcast_own_sum was shrunk down in new buffer; free old one */ + if (orig_node->bat_iv.bcast_own_sum != data_ptr) { + kfree(orig_node->bat_iv.bcast_own_sum); + orig_node->bat_iv.bcast_own_sum = data_ptr; + } +} + +/** * batadv_iv_ogm_orig_del_if - change the private structures of the orig_node to * exclude the removed interface * @orig_node: the orig_node that has to be changed @@ -186,60 +260,23 @@ unlock: static int batadv_iv_ogm_orig_del_if(struct batadv_orig_node *orig_node, int max_if_num, int del_if_num) { - int ret = -ENOMEM; - size_t chunk_size, if_offset; - void *data_ptr = NULL; - spin_lock_bh(&orig_node->bat_iv.ogm_cnt_lock); - /* last interface was removed */ - if (max_if_num == 0) - goto free_bcast_own; - - chunk_size = sizeof(unsigned long) * BATADV_NUM_WORDS; - data_ptr = kmalloc_array(max_if_num, chunk_size, GFP_ATOMIC); - if (!data_ptr) - goto unlock; - - /* copy first part */ - memcpy(data_ptr, orig_node->bat_iv.bcast_own, del_if_num * chunk_size); - - /* copy second part */ - if_offset = (del_if_num + 1) * chunk_siz
[PATCH 08/15] batman-adv: Fix checkpatch warning about 'unsigned' type
From: Sven Eckelmann checkpatch.pl warns about the use of 'unsigned' as a short form for 'unsigned int'. Signed-off-by: Sven Eckelmann Signed-off-by: Marek Lindner Signed-off-by: Antonio Quartulli --- net/batman-adv/fragmentation.c | 12 ++-- 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/net/batman-adv/fragmentation.c b/net/batman-adv/fragmentation.c index e6956d0746a2..65536db1bff7 100644 --- a/net/batman-adv/fragmentation.c +++ b/net/batman-adv/fragmentation.c @@ -407,8 +407,8 @@ static struct sk_buff *batadv_frag_create(struct sk_buff *skb, unsigned int mtu) { struct sk_buff *skb_fragment; - unsigned header_size = sizeof(*frag_head); - unsigned fragment_size = mtu - header_size; + unsigned int header_size = sizeof(*frag_head); + unsigned int fragment_size = mtu - header_size; skb_fragment = netdev_alloc_skb(NULL, mtu + ETH_HLEN); if (!skb_fragment) @@ -444,15 +444,15 @@ bool batadv_frag_send_packet(struct sk_buff *skb, struct batadv_hard_iface *primary_if = NULL; struct batadv_frag_packet frag_header; struct sk_buff *skb_fragment; - unsigned mtu = neigh_node->if_incoming->net_dev->mtu; - unsigned header_size = sizeof(frag_header); - unsigned max_fragment_size, max_packet_size; + unsigned int mtu = neigh_node->if_incoming->net_dev->mtu; + unsigned int header_size = sizeof(frag_header); + unsigned int max_fragment_size, max_packet_size; bool ret = false; /* To avoid merge and refragmentation at next-hops we never send * fragments larger than BATADV_FRAG_MAX_FRAG_SIZE */ - mtu = min_t(unsigned, mtu, BATADV_FRAG_MAX_FRAG_SIZE); + mtu = min_t(unsigned int, mtu, BATADV_FRAG_MAX_FRAG_SIZE); max_fragment_size = mtu - header_size; max_packet_size = max_fragment_size * BATADV_FRAG_MAX_FRAGMENTS; -- 2.8.2
[PATCH 05/15] batman-adv: use list_for_each_entry_safe
From: Geliang Tang Use list_for_each_entry_safe() instead of list_for_each_safe() to simplify the code. Signed-off-by: Geliang Tang Acked-by: Antonio Quartulli Reviewed-by: Sven Eckelmann Signed-off-by: Marek Lindner Signed-off-by: Antonio Quartulli --- net/batman-adv/icmp_socket.c | 22 +- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/net/batman-adv/icmp_socket.c b/net/batman-adv/icmp_socket.c index 14d0013b387e..8a5889d134bc 100644 --- a/net/batman-adv/icmp_socket.c +++ b/net/batman-adv/icmp_socket.c @@ -104,25 +104,21 @@ static int batadv_socket_open(struct inode *inode, struct file *file) static int batadv_socket_release(struct inode *inode, struct file *file) { - struct batadv_socket_client *socket_client = file->private_data; - struct batadv_socket_packet *socket_packet; - struct list_head *list_pos, *list_pos_tmp; + struct batadv_socket_client *client = file->private_data; + struct batadv_socket_packet *packet, *tmp; - spin_lock_bh(&socket_client->lock); + spin_lock_bh(&client->lock); /* for all packets in the queue ... */ - list_for_each_safe(list_pos, list_pos_tmp, &socket_client->queue_list) { - socket_packet = list_entry(list_pos, - struct batadv_socket_packet, list); - - list_del(list_pos); - kfree(socket_packet); + list_for_each_entry_safe(packet, tmp, &client->queue_list, list) { + list_del(&packet->list); + kfree(packet); } - batadv_socket_client_hash[socket_client->index] = NULL; - spin_unlock_bh(&socket_client->lock); + batadv_socket_client_hash[client->index] = NULL; + spin_unlock_bh(&client->lock); - kfree(socket_client); + kfree(client); module_put(THIS_MODULE); return 0; -- 2.8.2
[PATCH 07/15] batman-adv: fix wrong names in kerneldoc
Signed-off-by: Antonio Quartulli [s...@narfation.org: Fix additional names] Signed-off-by: Sven Eckelmann Signed-off-by: Marek Lindner --- net/batman-adv/bridge_loop_avoidance.c | 2 +- net/batman-adv/distributed-arp-table.c | 2 +- net/batman-adv/icmp_socket.c | 2 +- net/batman-adv/main.h | 3 ++- net/batman-adv/multicast.c | 11 ++- net/batman-adv/originator.c| 2 +- net/batman-adv/packet.h| 2 +- net/batman-adv/soft-interface.c| 2 +- 8 files changed, 14 insertions(+), 12 deletions(-) diff --git a/net/batman-adv/bridge_loop_avoidance.c b/net/batman-adv/bridge_loop_avoidance.c index cad8cb3a88f2..20b2fd9b3d72 100644 --- a/net/batman-adv/bridge_loop_avoidance.c +++ b/net/batman-adv/bridge_loop_avoidance.c @@ -1575,7 +1575,7 @@ int batadv_bla_is_backbone_gw(struct sk_buff *skb, } /** - * batadv_bla_init - free all bla structures + * batadv_bla_free - free all bla structures * @bat_priv: the bat priv with all the soft interface information * * for softinterface free or module unload diff --git a/net/batman-adv/distributed-arp-table.c b/net/batman-adv/distributed-arp-table.c index 33f273e5354b..f0548b4f66f4 100644 --- a/net/batman-adv/distributed-arp-table.c +++ b/net/batman-adv/distributed-arp-table.c @@ -717,7 +717,7 @@ void batadv_dat_status_update(struct net_device *net_dev) } /** - * batadv_gw_tvlv_ogm_handler_v1 - process incoming dat tvlv container + * batadv_dat_tvlv_ogm_handler_v1 - process incoming dat tvlv container * @bat_priv: the bat priv with all the soft interface information * @orig: the orig_node of the ogm * @flags: flags indicating the tvlv state (see batadv_tvlv_handler_flags) diff --git a/net/batman-adv/icmp_socket.c b/net/batman-adv/icmp_socket.c index 8a5889d134bc..777aea10cd8f 100644 --- a/net/batman-adv/icmp_socket.c +++ b/net/batman-adv/icmp_socket.c @@ -333,7 +333,7 @@ err: } /** - * batadv_socket_receive_packet - schedule an icmp packet to be sent to + * batadv_socket_add_packet - schedule an icmp packet to be sent to * userspace on an icmp socket. * @socket_client: the socket this packet belongs to * @icmph: pointer to the header of the icmp packet diff --git a/net/batman-adv/main.h b/net/batman-adv/main.h index 38e5587675cc..07a6042d0ad6 100644 --- a/net/batman-adv/main.h +++ b/net/batman-adv/main.h @@ -296,7 +296,8 @@ static inline bool batadv_compare_eth(const void *data1, const void *data2) } /** - * has_timed_out - compares current time (jiffies) and timestamp + timeout + * batadv_has_timed_out - compares current time (jiffies) and timestamp + + * timeout * @timestamp: base value to compare with (in jiffies) * @timeout: added to base value before comparing (in milliseconds) * diff --git a/net/batman-adv/multicast.c b/net/batman-adv/multicast.c index 8caa2c72efa3..c32f24fafe67 100644 --- a/net/batman-adv/multicast.c +++ b/net/batman-adv/multicast.c @@ -394,7 +394,8 @@ static int batadv_mcast_forw_mode_check(struct batadv_priv *bat_priv, } /** - * batadv_mcast_want_all_ip_count - count nodes with unspecific mcast interest + * batadv_mcast_forw_want_all_ip_count - count nodes with unspecific mcast + * interest * @bat_priv: the bat priv with all the soft interface information * @ethhdr: ethernet header of a packet * @@ -433,7 +434,7 @@ batadv_mcast_forw_tt_node_get(struct batadv_priv *bat_priv, } /** - * batadv_mcast_want_forw_ipv4_node_get - get a node with an ipv4 flag + * batadv_mcast_forw_ipv4_node_get - get a node with an ipv4 flag * @bat_priv: the bat priv with all the soft interface information * * Return: an orig_node which has the BATADV_MCAST_WANT_ALL_IPV4 flag set and @@ -460,7 +461,7 @@ batadv_mcast_forw_ipv4_node_get(struct batadv_priv *bat_priv) } /** - * batadv_mcast_want_forw_ipv6_node_get - get a node with an ipv6 flag + * batadv_mcast_forw_ipv6_node_get - get a node with an ipv6 flag * @bat_priv: the bat priv with all the soft interface information * * Return: an orig_node which has the BATADV_MCAST_WANT_ALL_IPV6 flag set @@ -487,7 +488,7 @@ batadv_mcast_forw_ipv6_node_get(struct batadv_priv *bat_priv) } /** - * batadv_mcast_want_forw_ip_node_get - get a node with an ipv4/ipv6 flag + * batadv_mcast_forw_ip_node_get - get a node with an ipv4/ipv6 flag * @bat_priv: the bat priv with all the soft interface information * @ethhdr: an ethernet header to determine the protocol family from * @@ -511,7 +512,7 @@ batadv_mcast_forw_ip_node_get(struct batadv_priv *bat_priv, } /** - * batadv_mcast_want_forw_unsnoop_node_get - get a node with an unsnoopable flag + * batadv_mcast_forw_unsnoop_node_get - get a node with an unsnoopable flag * @bat_priv: the bat priv with all the soft interface information * * Return: an orig_node which has the BATADV_MCAST_WANT_ALL_UNSNOOPABLES flag diff --git a/net/batman-adv/originator.c b/net/batman-adv/originator.c index
[PATCH 09/15] batman-adv: Fix kerneldoc for batadv_compare_claim
From: Sven Eckelmann Signed-off-by: Sven Eckelmann Signed-off-by: Marek Lindner Signed-off-by: Antonio Quartulli --- net/batman-adv/bridge_loop_avoidance.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/batman-adv/bridge_loop_avoidance.c b/net/batman-adv/bridge_loop_avoidance.c index 20b2fd9b3d72..60d33232bd10 100644 --- a/net/batman-adv/bridge_loop_avoidance.c +++ b/net/batman-adv/bridge_loop_avoidance.c @@ -120,7 +120,7 @@ static int batadv_compare_backbone_gw(const struct hlist_node *node, } /** - * batadv_compare_backbone_gw - compare address and vid of two claims + * batadv_compare_claim - compare address and vid of two claims * @node: list node of the first entry to compare * @data2: pointer to the second claims * -- 2.8.2
[PATCH 06/15] batman-adv: use to_delayed_work
From: Geliang Tang Use to_delayed_work() instead of open-coding it. Signed-off-by: Geliang Tang Reviewed-by: Sven Eckelmann Signed-off-by: Marek Lindner Signed-off-by: Antonio Quartulli --- net/batman-adv/bridge_loop_avoidance.c | 2 +- net/batman-adv/distributed-arp-table.c | 2 +- net/batman-adv/network-coding.c| 2 +- net/batman-adv/originator.c| 2 +- net/batman-adv/send.c | 4 ++-- net/batman-adv/translation-table.c | 2 +- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/net/batman-adv/bridge_loop_avoidance.c b/net/batman-adv/bridge_loop_avoidance.c index 56bc971e404b..cad8cb3a88f2 100644 --- a/net/batman-adv/bridge_loop_avoidance.c +++ b/net/batman-adv/bridge_loop_avoidance.c @@ -1303,7 +1303,7 @@ static void batadv_bla_periodic_work(struct work_struct *work) struct batadv_hard_iface *primary_if; int i; - delayed_work = container_of(work, struct delayed_work, work); + delayed_work = to_delayed_work(work); priv_bla = container_of(delayed_work, struct batadv_priv_bla, work); bat_priv = container_of(priv_bla, struct batadv_priv, bla); primary_if = batadv_primary_if_get_selected(bat_priv); diff --git a/net/batman-adv/distributed-arp-table.c b/net/batman-adv/distributed-arp-table.c index ce574e9cef3b..33f273e5354b 100644 --- a/net/batman-adv/distributed-arp-table.c +++ b/net/batman-adv/distributed-arp-table.c @@ -152,7 +152,7 @@ static void batadv_dat_purge(struct work_struct *work) struct batadv_priv_dat *priv_dat; struct batadv_priv *bat_priv; - delayed_work = container_of(work, struct delayed_work, work); + delayed_work = to_delayed_work(work); priv_dat = container_of(delayed_work, struct batadv_priv_dat, work); bat_priv = container_of(priv_dat, struct batadv_priv, dat); diff --git a/net/batman-adv/network-coding.c b/net/batman-adv/network-coding.c index b41719b6487a..0d3bf4368e9b 100644 --- a/net/batman-adv/network-coding.c +++ b/net/batman-adv/network-coding.c @@ -714,7 +714,7 @@ static void batadv_nc_worker(struct work_struct *work) struct batadv_priv *bat_priv; unsigned long timeout; - delayed_work = container_of(work, struct delayed_work, work); + delayed_work = to_delayed_work(work); priv_nc = container_of(delayed_work, struct batadv_priv_nc, work); bat_priv = container_of(priv_nc, struct batadv_priv, nc); diff --git a/net/batman-adv/originator.c b/net/batman-adv/originator.c index e4cbb0753e37..5b802f0dc24b 100644 --- a/net/batman-adv/originator.c +++ b/net/batman-adv/originator.c @@ -1222,7 +1222,7 @@ static void batadv_purge_orig(struct work_struct *work) struct delayed_work *delayed_work; struct batadv_priv *bat_priv; - delayed_work = container_of(work, struct delayed_work, work); + delayed_work = to_delayed_work(work); bat_priv = container_of(delayed_work, struct batadv_priv, orig_work); _batadv_purge_orig(bat_priv); queue_delayed_work(batadv_event_workqueue, diff --git a/net/batman-adv/send.c b/net/batman-adv/send.c index 3ce06e0a91b1..20076b4c5e1d 100644 --- a/net/batman-adv/send.c +++ b/net/batman-adv/send.c @@ -552,7 +552,7 @@ static void batadv_send_outstanding_bcast_packet(struct work_struct *work) struct net_device *soft_iface; struct batadv_priv *bat_priv; - delayed_work = container_of(work, struct delayed_work, work); + delayed_work = to_delayed_work(work); forw_packet = container_of(delayed_work, struct batadv_forw_packet, delayed_work); soft_iface = forw_packet->if_incoming->soft_iface; @@ -604,7 +604,7 @@ void batadv_send_outstanding_bat_ogm_packet(struct work_struct *work) struct batadv_forw_packet *forw_packet; struct batadv_priv *bat_priv; - delayed_work = container_of(work, struct delayed_work, work); + delayed_work = to_delayed_work(work); forw_packet = container_of(delayed_work, struct batadv_forw_packet, delayed_work); bat_priv = netdev_priv(forw_packet->if_incoming->soft_iface); diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c index 29fd62839fac..d44ce84626c5 100644 --- a/net/batman-adv/translation-table.c +++ b/net/batman-adv/translation-table.c @@ -3226,7 +3226,7 @@ static void batadv_tt_purge(struct work_struct *work) struct batadv_priv_tt *priv_tt; struct batadv_priv *bat_priv; - delayed_work = container_of(work, struct delayed_work, work); + delayed_work = to_delayed_work(work); priv_tt = container_of(delayed_work, struct batadv_priv_tt, work); bat_priv = container_of(priv_tt, struct batadv_priv, tt); -- 2.8.2
[PATCH 01/15] MAINTAINERS: Mark BATMAN ADVANCED mailing list as moderated
From: Sven Eckelmann The mailing list of b.a.t.m@lists.open-mesh.org is moderated for non-subscribers and non-whitelisted addresses. Such mails will be delayed but the sender will not be informed about the moderation. Signed-off-by: Sven Eckelmann Signed-off-by: Antonio Quartulli --- MAINTAINERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MAINTAINERS b/MAINTAINERS index ab008013cfec..22688419873f 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2203,7 +2203,7 @@ BATMAN ADVANCED M: Marek Lindner M: Simon Wunderlich M: Antonio Quartulli -L: b.a.t.m@lists.open-mesh.org +L: b.a.t.m@lists.open-mesh.org (moderated for non-subscribers) W: https://www.open-mesh.org/ Q: https://patchwork.open-mesh.org/project/batman/list/ S: Maintained -- 2.8.2
[PATCH 03/15] batman-adv: Start new development cycle
From: Simon Wunderlich Signed-off-by: Simon Wunderlich Signed-off-by: Antonio Quartulli --- net/batman-adv/main.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/batman-adv/main.h b/net/batman-adv/main.h index db4533631834..38e5587675cc 100644 --- a/net/batman-adv/main.h +++ b/net/batman-adv/main.h @@ -24,7 +24,7 @@ #define BATADV_DRIVER_DEVICE "batman-adv" #ifndef BATADV_SOURCE_VERSION -#define BATADV_SOURCE_VERSION "2016.1" +#define BATADV_SOURCE_VERSION "2016.2" #endif /* B.A.T.M.A.N. parameters */ -- 2.8.2
pull request: batman-adv 20160504
Hello David, this is a pull request intended for net-next. In this batch you don't have any patch that depends on our fixes, therefore you can safely merge it even if the net tree has not been merged yet. In this patchset you basically have some cleanup work, code refactoring, style fixes and two updates for the MAINTAINERS file. Please pull or let me know of any problem! Thanks a lot, Antonio The following changes since commit e03179fe78d5b39dbf3e8b0b50f7c406514b15c7: net: ethernet: fec_mpc52xx: move to new ethtool api {get|set}_link_ksettings (2016-05-03 13:03:53 -0400) are available in the git repository at: git://git.open-mesh.org/linux-merge.git tags/batman-adv-for-davem for you to fetch changes up to 64ae74455371a40bc9f9c8325eb4c37f2978c95f: batman-adv: Split batadv_iv_ogm_orig_del_if function (2016-05-04 02:22:03 +0800) In this pull request you have: - two changes to the MAINTAINERS file where one marks our mailing list as moderated and the other adds a missing documentation file - kernel-doc fixes - code refactoring and various cleanups Antonio Quartulli (2): batman-adv: use static string for table headers batman-adv: fix wrong names in kerneldoc Geliang Tang (2): batman-adv: use list_for_each_entry_safe batman-adv: use to_delayed_work Simon Wunderlich (4): batman-adv: Start new development cycle batman-adv: fix debuginfo macro style issue batman-adv: move and restructure batadv_v_ogm_forward batman-adv: Merge batadv_v_ogm_orig_update into batadv_v_ogm_route_update Sven Eckelmann (7): MAINTAINERS: Mark BATMAN ADVANCED mailing list as moderated MAINTAINERS: Add BATMAN ADVANCED documentation files batman-adv: Fix checkpatch warning about 'unsigned' type batman-adv: Fix kerneldoc for batadv_compare_claim batman-adv: Add kernel-doc for batadv_interface_rx batman-adv: Fix function names on new line starting with '*' batman-adv: Split batadv_iv_ogm_orig_del_if function MAINTAINERS| 5 +- net/batman-adv/bat_iv_ogm.c| 123 +--- net/batman-adv/bat_v.c | 9 +- net/batman-adv/bat_v_ogm.c | 205 - net/batman-adv/bridge_loop_avoidance.c | 19 ++- net/batman-adv/debugfs.c | 19 +-- net/batman-adv/distributed-arp-table.c | 8 +- net/batman-adv/fragmentation.c | 12 +- net/batman-adv/icmp_socket.c | 24 ++-- net/batman-adv/main.c | 8 +- net/batman-adv/main.h | 5 +- net/batman-adv/multicast.c | 11 +- net/batman-adv/network-coding.c| 20 ++-- net/batman-adv/originator.c| 4 +- net/batman-adv/packet.h| 2 +- net/batman-adv/send.c | 4 +- net/batman-adv/soft-interface.c| 20 +++- net/batman-adv/translation-table.c | 11 +- 18 files changed, 277 insertions(+), 232 deletions(-)
[PATCH 04/15] batman-adv: use static string for table headers
Use a static string when showing table headers rather then a nonsense parametric one with fixed arguments. It is easier to grep and it does not need to be recomputed at runtime each time. Reported-by: Joe Perches Signed-off-by: Antonio Quartulli [s...@narfation.org: fix conflicts with current version] Signed-off-by: Sven Eckelmann Signed-off-by: Marek Lindner --- net/batman-adv/bat_iv_ogm.c| 8 +++- net/batman-adv/bat_v.c | 9 - net/batman-adv/bridge_loop_avoidance.c | 7 +++ net/batman-adv/distributed-arp-table.c | 4 ++-- net/batman-adv/translation-table.c | 9 - 5 files changed, 16 insertions(+), 21 deletions(-) diff --git a/net/batman-adv/bat_iv_ogm.c b/net/batman-adv/bat_iv_ogm.c index cb2d1b9b0340..682fcaec56e6 100644 --- a/net/batman-adv/bat_iv_ogm.c +++ b/net/batman-adv/bat_iv_ogm.c @@ -1829,9 +1829,8 @@ static void batadv_iv_ogm_orig_print(struct batadv_priv *bat_priv, int batman_count = 0; u32 i; - seq_printf(seq, " %-15s %s (%s/%i) %17s [%10s]: %20s ...\n", - "Originator", "last-seen", "#", BATADV_TQ_MAX_VALUE, - "Nexthop", "outgoingIF", "Potential nexthops"); + seq_puts(seq, +" Originator last-seen (#/255) Nexthop [outgoingIF]: Potential nexthops ...\n"); for (i = 0; i < hash->size; i++) { head = &hash->table[i]; @@ -1911,8 +1910,7 @@ static void batadv_iv_neigh_print(struct batadv_priv *bat_priv, struct batadv_hard_iface *hard_iface; int batman_count = 0; - seq_printf(seq, " %10s%-13s %s\n", - "IF", "Neighbor", "last-seen"); + seq_puts(seq, " IFNeighbor last-seen\n"); rcu_read_lock(); list_for_each_entry_rcu(hard_iface, &batadv_hardif_list, list) { diff --git a/net/batman-adv/bat_v.c b/net/batman-adv/bat_v.c index 3315b9a598af..246f9e959849 100644 --- a/net/batman-adv/bat_v.c +++ b/net/batman-adv/bat_v.c @@ -151,8 +151,8 @@ static void batadv_v_neigh_print(struct batadv_priv *bat_priv, struct batadv_hard_iface *hard_iface; int batman_count = 0; - seq_printf(seq, " %-15s %s (%11s) [%10s]\n", "Neighbor", - "last-seen", "throughput", "IF"); + seq_puts(seq, +" Neighborlast-seen ( throughput) [IF]\n"); rcu_read_lock(); list_for_each_entry_rcu(hard_iface, &batadv_hardif_list, list) { @@ -191,9 +191,8 @@ static void batadv_v_orig_print(struct batadv_priv *bat_priv, int batman_count = 0; u32 i; - seq_printf(seq, " %-15s %s (%11s) %17s [%10s]: %20s ...\n", - "Originator", "last-seen", "throughput", "Nexthop", - "outgoingIF", "Potential nexthops"); + seq_puts(seq, +" Originator last-seen ( throughput) Nexthop [outgoingIF]: Potential nexthops ...\n"); for (i = 0; i < hash->size; i++) { head = &hash->table[i]; diff --git a/net/batman-adv/bridge_loop_avoidance.c b/net/batman-adv/bridge_loop_avoidance.c index 0a6c8b824a00..56bc971e404b 100644 --- a/net/batman-adv/bridge_loop_avoidance.c +++ b/net/batman-adv/bridge_loop_avoidance.c @@ -1815,8 +1815,8 @@ int batadv_bla_claim_table_seq_print_text(struct seq_file *seq, void *offset) "Claims announced for the mesh %s (orig %pM, group id %#.4x)\n", net_dev->name, primary_addr, ntohs(bat_priv->bla.claim_dest.group)); - seq_printf(seq, " %-17s%-5s%-17s [o] (%-6s)\n", - "Client", "VID", "Originator", "CRC"); + seq_puts(seq, +" Client VID Originator[o] (CRC )\n"); for (i = 0; i < hash->size; i++) { head = &hash->table[i]; @@ -1873,8 +1873,7 @@ int batadv_bla_backbone_table_seq_print_text(struct seq_file *seq, void *offset) "Backbones announced for the mesh %s (orig %pM, group id %#.4x)\n", net_dev->name, primary_addr, ntohs(bat_priv->bla.claim_dest.group)); - seq_printf(seq, " %-17s%-5s %-9s (%-6s)\n", - "Originator", "VID", "last seen", "CRC"); + seq_puts(seq, " Originator VID last seen (CRC )\n"); for (i = 0; i < hash->size; i++) { head = &hash->table[i]; diff --g
[PATCH 02/15] MAINTAINERS: Add BATMAN ADVANCED documentation files
From: Sven Eckelmann The sysfs ABI documentation files and the batman-adv.txt are maintained by the BATMAN ADVANCED maintainers and patches for them should therefore be sent to them. Signed-off-by: Sven Eckelmann Signed-off-by: Antonio Quartulli --- MAINTAINERS | 3 +++ 1 file changed, 3 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 22688419873f..8f32094f6922 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2207,6 +2207,9 @@ L:b.a.t.m@lists.open-mesh.org (moderated for non-subscribers) W: https://www.open-mesh.org/ Q: https://patchwork.open-mesh.org/project/batman/list/ S: Maintained +F: Documentation/ABI/testing/sysfs-class-net-batman-adv +F: Documentation/ABI/testing/sysfs-class-net-mesh +F: Documentation/networking/batman-adv.txt F: net/batman-adv/ BAYCOM/HDLCDRV DRIVERS FOR AX.25 -- 2.8.2
Re: pull request [net]: batman-adv 20160430
On Tue, May 03, 2016 at 12:18:13AM -0400, David Miller wrote: > Pulled, thanks Antonio. Thanks a lot David. We now have some patches for net-next that somewhat depend on the fixes you have recently pulled. Do you have any plan on merging net into net-next in the following days ? I am asking because I'd prefer to avoid you the hassle of dealing with the conflicts. Cheers, -- Antonio Quartulli signature.asc Description: Digital signature
[PATCH 1/4] batman-adv: fix DAT candidate selection (must use vid)
Now that DAT is VLAN aware, it must use the VID when computing the DHT address of the candidate nodes where an entry is going to be stored/retrieved. Fixes: be1db4f6615b ("batman-adv: make the Distributed ARP Table vlan aware") Signed-off-by: Antonio Quartulli [s...@narfation.org: fix conflicts with current version] Signed-off-by: Sven Eckelmann Signed-off-by: Marek Lindner --- net/batman-adv/distributed-arp-table.c | 17 ++--- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/net/batman-adv/distributed-arp-table.c b/net/batman-adv/distributed-arp-table.c index e96d7c745b4a..3e6b2624f980 100644 --- a/net/batman-adv/distributed-arp-table.c +++ b/net/batman-adv/distributed-arp-table.c @@ -568,6 +568,7 @@ static void batadv_choose_next_candidate(struct batadv_priv *bat_priv, * be sent to * @bat_priv: the bat priv with all the soft interface information * @ip_dst: ipv4 to look up in the DHT + * @vid: VLAN identifier * * An originator O is selected if and only if its DHT_ID value is one of three * closest values (from the LEFT, with wrap around if needed) then the hash @@ -576,7 +577,8 @@ static void batadv_choose_next_candidate(struct batadv_priv *bat_priv, * Return: the candidate array of size BATADV_DAT_CANDIDATE_NUM. */ static struct batadv_dat_candidate * -batadv_dat_select_candidates(struct batadv_priv *bat_priv, __be32 ip_dst) +batadv_dat_select_candidates(struct batadv_priv *bat_priv, __be32 ip_dst, +unsigned short vid) { int select; batadv_dat_addr_t last_max = BATADV_DAT_ADDR_MAX, ip_key; @@ -592,7 +594,7 @@ batadv_dat_select_candidates(struct batadv_priv *bat_priv, __be32 ip_dst) return NULL; dat.ip = ip_dst; - dat.vid = 0; + dat.vid = vid; ip_key = (batadv_dat_addr_t)batadv_hash_dat(&dat, BATADV_DAT_ADDR_MAX); @@ -612,6 +614,7 @@ batadv_dat_select_candidates(struct batadv_priv *bat_priv, __be32 ip_dst) * @bat_priv: the bat priv with all the soft interface information * @skb: payload to send * @ip: the DHT key + * @vid: VLAN identifier * @packet_subtype: unicast4addr packet subtype to use * * This function copies the skb with pskb_copy() and is sent as unicast packet @@ -622,7 +625,7 @@ batadv_dat_select_candidates(struct batadv_priv *bat_priv, __be32 ip_dst) */ static bool batadv_dat_send_data(struct batadv_priv *bat_priv, struct sk_buff *skb, __be32 ip, -int packet_subtype) +unsigned short vid, int packet_subtype) { int i; bool ret = false; @@ -631,7 +634,7 @@ static bool batadv_dat_send_data(struct batadv_priv *bat_priv, struct sk_buff *tmp_skb; struct batadv_dat_candidate *cand; - cand = batadv_dat_select_candidates(bat_priv, ip); + cand = batadv_dat_select_candidates(bat_priv, ip, vid); if (!cand) goto out; @@ -1022,7 +1025,7 @@ bool batadv_dat_snoop_outgoing_arp_request(struct batadv_priv *bat_priv, ret = true; } else { /* Send the request to the DHT */ - ret = batadv_dat_send_data(bat_priv, skb, ip_dst, + ret = batadv_dat_send_data(bat_priv, skb, ip_dst, vid, BATADV_P_DAT_DHT_GET); } out: @@ -1150,8 +1153,8 @@ void batadv_dat_snoop_outgoing_arp_reply(struct batadv_priv *bat_priv, /* Send the ARP reply to the candidates for both the IP addresses that * the node obtained from the ARP reply */ - batadv_dat_send_data(bat_priv, skb, ip_src, BATADV_P_DAT_DHT_PUT); - batadv_dat_send_data(bat_priv, skb, ip_dst, BATADV_P_DAT_DHT_PUT); + batadv_dat_send_data(bat_priv, skb, ip_src, vid, BATADV_P_DAT_DHT_PUT); + batadv_dat_send_data(bat_priv, skb, ip_dst, vid, BATADV_P_DAT_DHT_PUT); } /** -- 2.8.1
[PATCH 4/4] batman-adv: Fix reference counting of hardif_neigh_node object for neigh_node
From: Sven Eckelmann The batadv_neigh_node was specific to a batadv_hardif_neigh_node and held an implicit reference to it. But this reference was never stored in form of a pointer in the batadv_neigh_node itself. Instead batadv_neigh_node_release depends on a consistent state of hard_iface->neigh_list and that batadv_hardif_neigh_get always returns the batadv_hardif_neigh_node object which it has a reference for. But batadv_hardif_neigh_get cannot guarantee that because it is working only with rcu_read_lock on this list. It can therefore happen that a neigh_addr is in this list twice or that batadv_hardif_neigh_get cannot find the batadv_hardif_neigh_node for an neigh_addr due to some other list operations taking place at the same time. Instead add a batadv_hardif_neigh_node pointer directly in batadv_neigh_node which will be used for the reference counter decremented on release of batadv_neigh_node. Fixes: cef63419f7db ("batman-adv: add list of unique single hop neighbors per hard-interface") Signed-off-by: Sven Eckelmann Signed-off-by: Marek Lindner Signed-off-by: Antonio Quartulli --- net/batman-adv/originator.c | 16 +--- net/batman-adv/types.h | 2 ++ 2 files changed, 7 insertions(+), 11 deletions(-) diff --git a/net/batman-adv/originator.c b/net/batman-adv/originator.c index d52f67a0c057..c355a824713c 100644 --- a/net/batman-adv/originator.c +++ b/net/batman-adv/originator.c @@ -250,7 +250,6 @@ static void batadv_neigh_node_release(struct kref *ref) { struct hlist_node *node_tmp; struct batadv_neigh_node *neigh_node; - struct batadv_hardif_neigh_node *hardif_neigh; struct batadv_neigh_ifinfo *neigh_ifinfo; struct batadv_algo_ops *bao; @@ -262,13 +261,7 @@ static void batadv_neigh_node_release(struct kref *ref) batadv_neigh_ifinfo_put(neigh_ifinfo); } - hardif_neigh = batadv_hardif_neigh_get(neigh_node->if_incoming, - neigh_node->addr); - if (hardif_neigh) { - /* batadv_hardif_neigh_get() increases refcount too */ - batadv_hardif_neigh_put(hardif_neigh); - batadv_hardif_neigh_put(hardif_neigh); - } + batadv_hardif_neigh_put(neigh_node->hardif_neigh); if (bao->bat_neigh_free) bao->bat_neigh_free(neigh_node); @@ -665,6 +658,10 @@ batadv_neigh_node_new(struct batadv_orig_node *orig_node, neigh_node->orig_node = orig_node; neigh_node->last_seen = jiffies; + /* increment unique neighbor refcount */ + kref_get(&hardif_neigh->refcount); + neigh_node->hardif_neigh = hardif_neigh; + /* extra reference for return */ kref_init(&neigh_node->refcount); kref_get(&neigh_node->refcount); @@ -673,9 +670,6 @@ batadv_neigh_node_new(struct batadv_orig_node *orig_node, hlist_add_head_rcu(&neigh_node->list, &orig_node->neigh_list); spin_unlock_bh(&orig_node->neigh_list_lock); - /* increment unique neighbor refcount */ - kref_get(&hardif_neigh->refcount); - batadv_dbg(BATADV_DBG_BATMAN, orig_node->bat_priv, "Creating new neighbor %pM for orig_node %pM on interface %s\n", neigh_addr, orig_node->orig, hard_iface->net_dev->name); diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h index 65afd090ab3e..1e47fbe8bb7b 100644 --- a/net/batman-adv/types.h +++ b/net/batman-adv/types.h @@ -433,6 +433,7 @@ struct batadv_hardif_neigh_node { * @ifinfo_lock: lock protecting private ifinfo members and list * @if_incoming: pointer to incoming hard-interface * @last_seen: when last packet via this neighbor was received + * @hardif_neigh: hardif_neigh of this neighbor * @refcount: number of contexts the object is used * @rcu: struct used for freeing in an RCU-safe manner */ @@ -444,6 +445,7 @@ struct batadv_neigh_node { spinlock_t ifinfo_lock; /* protects ifinfo_list and its members */ struct batadv_hard_iface *if_incoming; unsigned long last_seen; + struct batadv_hardif_neigh_node *hardif_neigh; struct kref refcount; struct rcu_head rcu; }; -- 2.8.1
[PATCH 2/4] batman-adv: B.A.T.M.A.N V - make sure iface is reactivated upon NETDEV_UP event
At the moment there is no explicit reactivation of an hard-interface upon NETDEV_UP event. In case of B.A.T.M.A.N. IV the interface is reactivated as soon as the next OGM is scheduled for sending, but this mechanism does not work with B.A.T.M.A.N. V. The latter does not rely on the same scheduling mechanism as its predecessor and for this reason the hard-interface remains deactivated forever after being brought down once. This patch fixes the reactivation mechanism by adding a new routing API which explicitly allows each algorithm to perform any needed operation upon interface re-activation. Such API is optional and is implemented by B.A.T.M.A.N. V only and it just takes care of setting the iface status to ACTIVE Signed-off-by: Antonio Quartulli Signed-off-by: Marek Lindner --- net/batman-adv/bat_v.c | 12 net/batman-adv/hard-interface.c | 3 +++ net/batman-adv/types.h | 3 +++ 3 files changed, 18 insertions(+) diff --git a/net/batman-adv/bat_v.c b/net/batman-adv/bat_v.c index 3315b9a598af..4026f198a734 100644 --- a/net/batman-adv/bat_v.c +++ b/net/batman-adv/bat_v.c @@ -32,10 +32,21 @@ #include "bat_v_elp.h" #include "bat_v_ogm.h" +#include "hard-interface.h" #include "hash.h" #include "originator.h" #include "packet.h" +static void batadv_v_iface_activate(struct batadv_hard_iface *hard_iface) +{ + /* B.A.T.M.A.N. V does not use any queuing mechanism, therefore it can +* set the interface as ACTIVE right away, without any risk of race +* condition +*/ + if (hard_iface->if_status == BATADV_IF_TO_BE_ACTIVATED) + hard_iface->if_status = BATADV_IF_ACTIVE; +} + static int batadv_v_iface_enable(struct batadv_hard_iface *hard_iface) { int ret; @@ -274,6 +285,7 @@ static bool batadv_v_neigh_is_sob(struct batadv_neigh_node *neigh1, static struct batadv_algo_ops batadv_batman_v __read_mostly = { .name = "BATMAN_V", + .bat_iface_activate = batadv_v_iface_activate, .bat_iface_enable = batadv_v_iface_enable, .bat_iface_disable = batadv_v_iface_disable, .bat_iface_update_mac = batadv_v_iface_update_mac, diff --git a/net/batman-adv/hard-interface.c b/net/batman-adv/hard-interface.c index c61d5b0b24d2..0a7deaf2670a 100644 --- a/net/batman-adv/hard-interface.c +++ b/net/batman-adv/hard-interface.c @@ -407,6 +407,9 @@ batadv_hardif_activate_interface(struct batadv_hard_iface *hard_iface) batadv_update_min_mtu(hard_iface->soft_iface); + if (bat_priv->bat_algo_ops->bat_iface_activate) + bat_priv->bat_algo_ops->bat_iface_activate(hard_iface); + out: if (primary_if) batadv_hardif_put(primary_if); diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h index 9abfb3e73c34..443e9b84e07d 100644 --- a/net/batman-adv/types.h +++ b/net/batman-adv/types.h @@ -1250,6 +1250,8 @@ struct batadv_forw_packet { * struct batadv_algo_ops - mesh algorithm callbacks * @list: list node for the batadv_algo_list * @name: name of the algorithm + * @bat_iface_activate: start routing mechanisms when hard-interface is brought + * up * @bat_iface_enable: init routing info when hard-interface is enabled * @bat_iface_disable: de-init routing info when hard-interface is disabled * @bat_iface_update_mac: (re-)init mac addresses of the protocol information @@ -1277,6 +1279,7 @@ struct batadv_forw_packet { struct batadv_algo_ops { struct hlist_node list; char *name; + void (*bat_iface_activate)(struct batadv_hard_iface *hard_iface); int (*bat_iface_enable)(struct batadv_hard_iface *hard_iface); void (*bat_iface_disable)(struct batadv_hard_iface *hard_iface); void (*bat_iface_update_mac)(struct batadv_hard_iface *hard_iface); -- 2.8.1
pull request [net]: batman-adv 20160430
Hello David, this is another pull request intended for net. I know that I sent another batch a few days ago, but after having gone through my queue I thought that merging these last 4 patches would still be worth it (there won't be any other pull request for linux-4.6 :)). The description of the changes follows below. Please pull or let me know of any issue! Thanks a lot, Antonio The following changes since commit 1dfcd832b1a9ed45edac15b31d079b805fa0ae2a: Merge branch 'bpf-fixes' (2016-04-28 17:29:46 -0400) are available in the git repository at: git://git.open-mesh.org/linux-merge.git tags/batman-adv-fix-for-davem for you to fetch changes up to abe59c65225ccd63a5964e2f2a73dd2995b948e7: batman-adv: Fix reference counting of hardif_neigh_node object for neigh_node (2016-04-29 19:46:11 +0800) In this small batch of patches you have: - a fix for our Distributed ARP Table that makes sure that the input provided to the hash function during a query is the same as the one provided during an insert (so to prevent false negatives), by Antonio Quartulli - a fix for our new protocol implementation B.A.T.M.A.N. V that ensures that a hard interface is properly re-activated when it is brought down and then up again, by Antonio Quartulli - two fixes respectively to the reference counting of the tt_local_entry and neigh_node objects, by Sven Eckelmann. Such bug is rather severe as it would prevent the netdev objects references by batman-adv from being released after shutdown. -------- Antonio Quartulli (2): batman-adv: fix DAT candidate selection (must use vid) batman-adv: B.A.T.M.A.N V - make sure iface is reactivated upon NETDEV_UP event Sven Eckelmann (2): batman-adv: Fix reference counting of vlan object for tt_local_entry batman-adv: Fix reference counting of hardif_neigh_node object for neigh_node net/batman-adv/bat_v.c | 12 ++ net/batman-adv/distributed-arp-table.c | 17 -- net/batman-adv/hard-interface.c| 3 +++ net/batman-adv/originator.c| 16 - net/batman-adv/translation-table.c | 42 -- net/batman-adv/types.h | 7 ++ 6 files changed, 41 insertions(+), 56 deletions(-)
[PATCH 3/4] batman-adv: Fix reference counting of vlan object for tt_local_entry
From: Sven Eckelmann The batadv_tt_local_entry was specific to a batadv_softif_vlan and held an implicit reference to it. But this reference was never stored in form of a pointer in the tt_local_entry itself. Instead batadv_tt_local_remove, batadv_tt_local_table_free and batadv_tt_local_purge_pending_clients depend on a consistent state of bat_priv->softif_vlan_list and that batadv_softif_vlan_get always returns the batadv_softif_vlan object which it has a reference for. But batadv_softif_vlan_get cannot guarantee that because it is working only with rcu_read_lock on this list. It can therefore happen that an vid is in this list twice or that batadv_softif_vlan_get cannot find the batadv_softif_vlan for an vid due to some other list operations taking place at the same time. Instead add a batadv_softif_vlan pointer directly in batadv_tt_local_entry which will be used for the reference counter decremented on release of batadv_tt_local_entry. Fixes: 35df3b298fc8 ("batman-adv: fix TT VLAN inconsistency on VLAN re-add") Signed-off-by: Sven Eckelmann Acked-by: Antonio Quartulli Signed-off-by: Marek Lindner Signed-off-by: Antonio Quartulli --- net/batman-adv/translation-table.c | 42 -- net/batman-adv/types.h | 2 ++ 2 files changed, 6 insertions(+), 38 deletions(-) diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c index 0b43e86328a5..9b4551a86535 100644 --- a/net/batman-adv/translation-table.c +++ b/net/batman-adv/translation-table.c @@ -215,6 +215,8 @@ static void batadv_tt_local_entry_release(struct kref *ref) tt_local_entry = container_of(ref, struct batadv_tt_local_entry, common.refcount); + batadv_softif_vlan_put(tt_local_entry->vlan); + kfree_rcu(tt_local_entry, common.rcu); } @@ -673,6 +675,7 @@ bool batadv_tt_local_add(struct net_device *soft_iface, const u8 *addr, kref_get(&tt_local->common.refcount); tt_local->last_seen = jiffies; tt_local->common.added_at = tt_local->last_seen; + tt_local->vlan = vlan; /* the batman interface mac and multicast addresses should never be * purged @@ -991,7 +994,6 @@ int batadv_tt_local_seq_print_text(struct seq_file *seq, void *offset) struct batadv_tt_common_entry *tt_common_entry; struct batadv_tt_local_entry *tt_local; struct batadv_hard_iface *primary_if; - struct batadv_softif_vlan *vlan; struct hlist_head *head; unsigned short vid; u32 i; @@ -1027,14 +1029,6 @@ int batadv_tt_local_seq_print_text(struct seq_file *seq, void *offset) last_seen_msecs = last_seen_msecs % 1000; no_purge = tt_common_entry->flags & np_flag; - - vlan = batadv_softif_vlan_get(bat_priv, vid); - if (!vlan) { - seq_printf(seq, "Cannot retrieve VLAN %d\n", - BATADV_PRINT_VID(vid)); - continue; - } - seq_printf(seq, " * %pM %4i [%c%c%c%c%c%c] %3u.%03u (%#.8x)\n", tt_common_entry->addr, @@ -1052,9 +1046,7 @@ int batadv_tt_local_seq_print_text(struct seq_file *seq, void *offset) BATADV_TT_CLIENT_ISOLA) ? 'I' : '.'), no_purge ? 0 : last_seen_secs, no_purge ? 0 : last_seen_msecs, - vlan->tt.crc); - - batadv_softif_vlan_put(vlan); + tt_local->vlan->tt.crc); } rcu_read_unlock(); } @@ -1099,7 +1091,6 @@ u16 batadv_tt_local_remove(struct batadv_priv *bat_priv, const u8 *addr, { struct batadv_tt_local_entry *tt_local_entry; u16 flags, curr_flags = BATADV_NO_FLAGS; - struct batadv_softif_vlan *vlan; void *tt_entry_exists; tt_local_entry = batadv_tt_local_hash_find(bat_priv, addr, vid); @@ -1139,14 +1130,6 @@ u16 batadv_tt_local_remove(struct batadv_priv *bat_priv, const u8 *addr, /* extra call to free the local tt entry */ batadv_tt_local_entry_put(tt_local_entry); - /* decrease the reference held for this vlan */ - vlan = batadv_softif_vlan_get(bat_priv, vid); - if (!vlan) - goto out; - - batadv_softif_vlan_put(vlan); - batadv_softif_vlan_put(vlan); - out: if (tt_local_entry) batadv_tt_local_entry_put(tt_local_entry); @@ -1219,7 +1202,6 @@ static void batadv_tt_local_table_free(struct batadv_priv *bat_priv) spinlock_t *list_lock; /* protects write access to the hash lists *
Re: pull request [net]: batman-adv-0160426
On Thu, Apr 28, 2016 at 04:43:51PM -0400, David Miller wrote: > > Patch 2 and 3 have no "Fixes:" tag because the offending commits date > > back to when batman-adv was not yet officially in the net tree. > > This is not correct. Instead, in the future, you should provide a > Fixes: tag that indicates the commit that merged batman-adv into the > upstream tree initially. makes sense. Thanks for the suggestion! -- Antonio Quartulli signature.asc Description: Digital signature
[PATCH 5/5] batman-adv: Fix broadcast/ogm queue limit on a removed interface
From: Linus Lüssing When removing a single interface while a broadcast or ogm packet is still pending then we will free the forward packet without releasing the queue slots again. This patch is supposed to fix this issue. Fixes: 6d5808d4ae1b ("batman-adv: Add missing hardif_free_ref in forw_packet_free") Signed-off-by: Linus Lüssing [s...@narfation.org: fix conflicts with current version] Signed-off-by: Sven Eckelmann Signed-off-by: Marek Lindner Signed-off-by: Antonio Quartulli --- net/batman-adv/send.c | 6 ++ 1 file changed, 6 insertions(+) diff --git a/net/batman-adv/send.c b/net/batman-adv/send.c index 3ce06e0a91b1..76417850d3fc 100644 --- a/net/batman-adv/send.c +++ b/net/batman-adv/send.c @@ -675,6 +675,9 @@ batadv_purge_outstanding_packets(struct batadv_priv *bat_priv, if (pending) { hlist_del(&forw_packet->list); + if (!forw_packet->own) + atomic_inc(&bat_priv->bcast_queue_left); + batadv_forw_packet_free(forw_packet); } } @@ -702,6 +705,9 @@ batadv_purge_outstanding_packets(struct batadv_priv *bat_priv, if (pending) { hlist_del(&forw_packet->list); + if (!forw_packet->own) + atomic_inc(&bat_priv->batman_queue_left); + batadv_forw_packet_free(forw_packet); } } -- 2.8.1
[PATCH 4/5] batman-adv: Reduce refcnt of removed router when updating route
From: Sven Eckelmann _batadv_update_route rcu_derefences orig_ifinfo->router outside of a spinlock protected region to print some information messages to the debug log. But this pointer is not checked again when the new pointer is assigned in the spinlock protected region. Thus is can happen that the value of orig_ifinfo->router changed in the meantime and thus the reference counter of the wrong router gets reduced after the spinlock protected region. Just rcu_dereferencing the value of orig_ifinfo->router inside the spinlock protected region (which also set the new pointer) is enough to get the correct old router object. Fixes: e1a5382f978b ("batman-adv: Make orig_node->router an rcu protected pointer") Signed-off-by: Sven Eckelmann Signed-off-by: Marek Lindner Signed-off-by: Antonio Quartulli --- net/batman-adv/routing.c | 9 + 1 file changed, 9 insertions(+) diff --git a/net/batman-adv/routing.c b/net/batman-adv/routing.c index 4dd646a52f1a..b781bf753250 100644 --- a/net/batman-adv/routing.c +++ b/net/batman-adv/routing.c @@ -105,6 +105,15 @@ static void _batadv_update_route(struct batadv_priv *bat_priv, neigh_node = NULL; spin_lock_bh(&orig_node->neigh_list_lock); + /* curr_router used earlier may not be the current orig_ifinfo->router +* anymore because it was dereferenced outside of the neigh_list_lock +* protected region. After the new best neighbor has replace the current +* best neighbor the reference counter needs to decrease. Consequently, +* the code needs to ensure the curr_router variable contains a pointer +* to the replaced best neighbor. +*/ + curr_router = rcu_dereference_protected(orig_ifinfo->router, true); + rcu_assign_pointer(orig_ifinfo->router, neigh_node); spin_unlock_bh(&orig_node->neigh_list_lock); batadv_orig_ifinfo_put(orig_ifinfo); -- 2.8.1
[PATCH 2/5] batman-adv: init neigh node last seen field
From: Marek Lindner Signed-off-by: Marek Lindner [s...@narfation.org: fix conflicts with current version] Signed-off-by: Sven Eckelmann Signed-off-by: Antonio Quartulli --- net/batman-adv/originator.c | 1 + 1 file changed, 1 insertion(+) diff --git a/net/batman-adv/originator.c b/net/batman-adv/originator.c index e4cbb0753e37..d52f67a0c057 100644 --- a/net/batman-adv/originator.c +++ b/net/batman-adv/originator.c @@ -663,6 +663,7 @@ batadv_neigh_node_new(struct batadv_orig_node *orig_node, ether_addr_copy(neigh_node->addr, neigh_addr); neigh_node->if_incoming = hard_iface; neigh_node->orig_node = orig_node; + neigh_node->last_seen = jiffies; /* extra reference for return */ kref_init(&neigh_node->refcount); -- 2.8.1
[PATCH 3/5] batman-adv: Deactivate TO_BE_ACTIVATED hardif on shutdown
From: Sven Eckelmann The shutdown of an batman-adv interface can happen with one of its slave interfaces still being in the BATADV_IF_TO_BE_ACTIVATED state. A possible reason for it is that the routing algorithm BATMAN_V was selected and batadv_schedule_bat_ogm was not yet called for this interface. This slave interface still has to be set to BATADV_IF_INACTIVE or the batman-adv interface will never reduce its usage counter and thus never gets shutdown. This problem can be simulated via: $ modprobe dummy $ modprobe batman-adv routing_algo=BATMAN_V $ ip link add bat0 type batadv $ ip link set dummy0 master bat0 $ ip link set dummy0 up $ ip link del bat0 unregister_netdevice: waiting for bat0 to become free. Usage count = 3 Reported-by: Matthias Schiffer Signed-off-by: Sven Eckelmann Signed-off-by: Marek Lindner Signed-off-by: Antonio Quartulli --- net/batman-adv/hard-interface.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/net/batman-adv/hard-interface.c b/net/batman-adv/hard-interface.c index b22b2775a0a5..c61d5b0b24d2 100644 --- a/net/batman-adv/hard-interface.c +++ b/net/batman-adv/hard-interface.c @@ -572,8 +572,7 @@ void batadv_hardif_disable_interface(struct batadv_hard_iface *hard_iface, struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface); struct batadv_hard_iface *primary_if = NULL; - if (hard_iface->if_status == BATADV_IF_ACTIVE) - batadv_hardif_deactivate_interface(hard_iface); + batadv_hardif_deactivate_interface(hard_iface); if (hard_iface->if_status != BATADV_IF_INACTIVE) goto out; -- 2.8.1
[PATCH 1/5] batman-adv: Check skb size before using encapsulated ETH+VLAN header
From: Sven Eckelmann The encapsulated ethernet and VLAN header may be outside the received ethernet frame. Thus the skb buffer size has to be checked before it can be parsed to find out if it encapsulates another batman-adv packet. Fixes: 420193573f11 ("batman-adv: softif bridge loop avoidance") Signed-off-by: Sven Eckelmann Signed-off-by: Marek Lindner Signed-off-by: Antonio Quartulli --- net/batman-adv/soft-interface.c | 8 ++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/net/batman-adv/soft-interface.c b/net/batman-adv/soft-interface.c index 0710379491bf..8a136b6a1ff0 100644 --- a/net/batman-adv/soft-interface.c +++ b/net/batman-adv/soft-interface.c @@ -408,11 +408,17 @@ void batadv_interface_rx(struct net_device *soft_iface, */ nf_reset(skb); + if (unlikely(!pskb_may_pull(skb, ETH_HLEN))) + goto dropped; + vid = batadv_get_vid(skb, 0); ethhdr = eth_hdr(skb); switch (ntohs(ethhdr->h_proto)) { case ETH_P_8021Q: + if (!pskb_may_pull(skb, VLAN_ETH_HLEN)) + goto dropped; + vhdr = (struct vlan_ethhdr *)skb->data; if (vhdr->h_vlan_encapsulated_proto != ethertype) @@ -424,8 +430,6 @@ void batadv_interface_rx(struct net_device *soft_iface, } /* skb->dev & skb->pkt_type are set here */ - if (unlikely(!pskb_may_pull(skb, ETH_HLEN))) - goto dropped; skb->protocol = eth_type_trans(skb, soft_iface); /* should not be necessary anymore as we use skb_pull_rcsum() -- 2.8.1
pull request [net]: batman-adv-0160426
Hi David, this is a batch intended for net. Changes are quite small, therefore I hope it is not a big deal to include them at this point of the release cycle. In this patchset you can find the following fixes: 1) check skb size to avoid reading beyond its border when delivering payloads, by Sven Eckelmann 2) initialize last_seen time in neigh_node object to prevent cleanup routine from accidentally purge it, by Marek Lindner 3) release "recently added" slave interfaces upon virtual/batman interface shutdown, by Sven Eckelmann 4) properly decrease router object reference counter upon routing table update, by Sven Eckelmann 5) release queue slots when purging OGM packets of deactivating slave interface, by Linus Lüssing Patch 2 and 3 have no "Fixes:" tag because the offending commits date back to when batman-adv was not yet officially in the net tree. Note that all these changes are fixing very old commits and therefore it would be nice if you could queue them for *stable*. Please pull or let me know of any issue! Thanks a lot, Antonio The following changes since commit 5f44abd041c5f3be76d57579ab254d78e601315b: Merge tag 'rtc-4.6-3' of git://git.kernel.org/pub/scm/linux/kernel/git/abelloni/linux (2016-04-21 15:41:13 -0700) are available in the git repository at: git://git.open-mesh.org/linux-merge.git tags/batman-adv-fix-for-davem for you to fetch changes up to c4fdb6cff2aa0ae740c5f19b6f745cbbe786d42f: batman-adv: Fix broadcast/ogm queue limit on a removed interface (2016-04-24 15:41:56 +0800) In this patchset you can find the following fixes: 1) check skb size to avoid reading beyond its border when delivering payloads, by Sven Eckelmann 2) initialize last_seen time in neigh_node object to prevent cleanup routine from accidentally purge it, by Marek Lindner 3) release "recently added" slave interfaces upon virtual/batman interface shutdown, by Sven Eckelmann 4) properly decrease router object reference counter upon routing table update, by Sven Eckelmann 5) release queue slots when purging OGM packets of deactivating slave interface, by Linus Lüssing Patch 2 and 3 have no "Fixes:" tag because the offending commits date back to when batman-adv was not yet officially in the net tree. Linus Lüssing (1): batman-adv: Fix broadcast/ogm queue limit on a removed interface Marek Lindner (1): batman-adv: init neigh node last seen field Sven Eckelmann (3): batman-adv: Check skb size before using encapsulated ETH+VLAN header batman-adv: Deactivate TO_BE_ACTIVATED hardif on shutdown batman-adv: Reduce refcnt of removed router when updating route net/batman-adv/hard-interface.c | 3 +-- net/batman-adv/originator.c | 1 + net/batman-adv/routing.c| 9 + net/batman-adv/send.c | 6 ++ net/batman-adv/soft-interface.c | 8 ++-- 5 files changed, 23 insertions(+), 4 deletions(-)
Re: [PATCH] batman-adv: Less function calls in batadv_is_ap_isolated() after error detection
On Mon, Mar 14, 2016 at 03:25:02PM -0400, David Miller wrote: > From: SF Markus Elfring > Date: Fri, 11 Mar 2016 13:40:56 +0100 > > > From: Markus Elfring > > Date: Fri, 11 Mar 2016 13:10:20 +0100 > > > > The variables "tt_local_entry" and "tt_global_entry" were eventually > > checked again despite of a corresponding null pointer test before. > > > > * Avoid this double check by reordering a function call sequence > > and the better selection of jump targets. > > > > * Omit the initialisation for these variables at the beginning then. > > > > Signed-off-by: Markus Elfring > > I am assuming Antonio will take this in via his tree. > Yeah, it will go through our tree. Still under review right now. Cheers, -- Antonio Quartulli signature.asc Description: Digital signature
Re: [PATCH] batman-adv: clarify CFG80211 dependency
On Wed, Mar 02, 2016 at 02:54:35PM +0100, Arnd Bergmann wrote: > The driver calls cfg80211_get_station, which may be part of a > module, so we must not enable BATMAN_ADV_BATMAN_V if > BATMAN_ADV=y and CFG80211=m: > > net/built-in.o: In function `batadv_v_elp_get_throughput': > (text+0x5c62c): undefined reference to `cfg80211_get_station' > > This clarifies the dependency to cover all combinations. > > Signed-off-by: Arnd Bergmann > Fixes: c833484e5f38 ("batman-adv: ELP - compute the metric based on the > estimated throughput") Acked-by: Antonio Quartulli Thanks a lot Arnd! David, could you please merge this change in net-next directly ? Regards, -- Antonio Quartulli signature.asc Description: Digital signature
[PATCH 11/15] batman-adv: B.A.T.M.A.N. V - implement neighbor comparison API calls
From: Antonio Quartulli Signed-off-by: Antonio Quartulli Signed-off-by: Marek Lindner --- net/batman-adv/bat_v.c | 38 ++ 1 file changed, 38 insertions(+) diff --git a/net/batman-adv/bat_v.c b/net/batman-adv/bat_v.c index ff31f2af9cfe..953c0d150231 100644 --- a/net/batman-adv/bat_v.c +++ b/net/batman-adv/bat_v.c @@ -19,12 +19,15 @@ #include "main.h" #include +#include #include #include +#include #include #include "bat_v_elp.h" #include "bat_v_ogm.h" +#include "originator.h" #include "packet.h" static int batadv_v_iface_enable(struct batadv_hard_iface *hard_iface) @@ -78,6 +81,39 @@ static void batadv_v_ogm_emit(struct batadv_forw_packet *forw_packet) { } +static int batadv_v_neigh_cmp(struct batadv_neigh_node *neigh1, + struct batadv_hard_iface *if_outgoing1, + struct batadv_neigh_node *neigh2, + struct batadv_hard_iface *if_outgoing2) +{ + struct batadv_neigh_ifinfo *ifinfo1, *ifinfo2; + + ifinfo1 = batadv_neigh_ifinfo_get(neigh1, if_outgoing1); + ifinfo2 = batadv_neigh_ifinfo_get(neigh2, if_outgoing2); + + if (WARN_ON(!ifinfo1 || !ifinfo2)) + return 0; + + return ifinfo1->bat_v.throughput - ifinfo2->bat_v.throughput; +} + +static bool batadv_v_neigh_is_sob(struct batadv_neigh_node *neigh1, + struct batadv_hard_iface *if_outgoing1, + struct batadv_neigh_node *neigh2, + struct batadv_hard_iface *if_outgoing2) +{ + struct batadv_neigh_ifinfo *ifinfo1, *ifinfo2; + u32 threshold; + + ifinfo1 = batadv_neigh_ifinfo_get(neigh1, if_outgoing1); + ifinfo2 = batadv_neigh_ifinfo_get(neigh2, if_outgoing2); + + threshold = ifinfo1->bat_v.throughput / 4; + threshold = ifinfo1->bat_v.throughput - threshold; + + return ifinfo2->bat_v.throughput > threshold; +} + static struct batadv_algo_ops batadv_batman_v __read_mostly = { .name = "BATMAN_V", .bat_iface_enable = batadv_v_iface_enable, @@ -87,6 +123,8 @@ static struct batadv_algo_ops batadv_batman_v __read_mostly = { .bat_hardif_neigh_init = batadv_v_hardif_neigh_init, .bat_ogm_emit = batadv_v_ogm_emit, .bat_ogm_schedule = batadv_v_ogm_schedule, + .bat_neigh_cmp = batadv_v_neigh_cmp, + .bat_neigh_is_similar_or_better = batadv_v_neigh_is_sob, }; /** -- 2.7.2
[PATCH 12/15] batman-adv: B.A.T.M.A.N. V - implement bat_orig_print API
From: Antonio Quartulli Signed-off-by: Antonio Quartulli Signed-off-by: Marek Lindner --- net/batman-adv/bat_v.c | 105 + 1 file changed, 105 insertions(+) diff --git a/net/batman-adv/bat_v.c b/net/batman-adv/bat_v.c index 953c0d150231..a90117c9a861 100644 --- a/net/batman-adv/bat_v.c +++ b/net/batman-adv/bat_v.c @@ -22,11 +22,17 @@ #include #include #include +#include +#include +#include +#include +#include #include #include #include "bat_v_elp.h" #include "bat_v_ogm.h" +#include "hash.h" #include "originator.h" #include "packet.h" @@ -81,6 +87,104 @@ static void batadv_v_ogm_emit(struct batadv_forw_packet *forw_packet) { } +/** + * batadv_v_orig_print_neigh - print neighbors for the originator table + * @orig_node: the orig_node for which the neighbors are printed + * @if_outgoing: outgoing interface for these entries + * @seq: debugfs table seq_file struct + * + * Must be called while holding an rcu lock. + */ +static void +batadv_v_orig_print_neigh(struct batadv_orig_node *orig_node, + struct batadv_hard_iface *if_outgoing, + struct seq_file *seq) +{ + struct batadv_neigh_node *neigh_node; + struct batadv_neigh_ifinfo *n_ifinfo; + + hlist_for_each_entry_rcu(neigh_node, &orig_node->neigh_list, list) { + n_ifinfo = batadv_neigh_ifinfo_get(neigh_node, if_outgoing); + if (!n_ifinfo) + continue; + + seq_printf(seq, " %pM (%9u.%1u)", + neigh_node->addr, + n_ifinfo->bat_v.throughput / 10, + n_ifinfo->bat_v.throughput % 10); + + batadv_neigh_ifinfo_put(n_ifinfo); + } +} + +/** + * batadv_v_orig_print - print the originator table + * @bat_priv: the bat priv with all the soft interface information + * @seq: debugfs table seq_file struct + * @if_outgoing: the outgoing interface for which this should be printed + */ +static void batadv_v_orig_print(struct batadv_priv *bat_priv, + struct seq_file *seq, + struct batadv_hard_iface *if_outgoing) +{ + struct batadv_neigh_node *neigh_node; + struct batadv_hashtable *hash = bat_priv->orig_hash; + int last_seen_msecs, last_seen_secs; + struct batadv_orig_node *orig_node; + struct batadv_neigh_ifinfo *n_ifinfo; + unsigned long last_seen_jiffies; + struct hlist_head *head; + int batman_count = 0; + u32 i; + + seq_printf(seq, " %-15s %s (%11s) %17s [%10s]: %20s ...\n", + "Originator", "last-seen", "throughput", "Nexthop", + "outgoingIF", "Potential nexthops"); + + for (i = 0; i < hash->size; i++) { + head = &hash->table[i]; + + rcu_read_lock(); + hlist_for_each_entry_rcu(orig_node, head, hash_entry) { + neigh_node = batadv_orig_router_get(orig_node, + if_outgoing); + if (!neigh_node) + continue; + + n_ifinfo = batadv_neigh_ifinfo_get(neigh_node, + if_outgoing); + if (!n_ifinfo) + goto next; + + last_seen_jiffies = jiffies - orig_node->last_seen; + last_seen_msecs = jiffies_to_msecs(last_seen_jiffies); + last_seen_secs = last_seen_msecs / 1000; + last_seen_msecs = last_seen_msecs % 1000; + + seq_printf(seq, "%pM %4i.%03is (%9u.%1u) %pM [%10s]:", + orig_node->orig, last_seen_secs, + last_seen_msecs, + n_ifinfo->bat_v.throughput / 10, + n_ifinfo->bat_v.throughput % 10, + neigh_node->addr, + neigh_node->if_incoming->net_dev->name); + + batadv_v_orig_print_neigh(orig_node, if_outgoing, seq); + seq_puts(seq, "\n"); + batman_count++; + +next: + batadv_neigh_node_put(neigh_node); + if (n_ifinfo) + batadv_neigh_ifinfo_put(n_ifinfo); + } + rcu_read_unlock(); + } + + if (batman_count == 0) + seq_puts(seq, "No batman nodes in range ...\n"); +} + static int batadv_v_neigh_cmp(struct batadv_neigh_node *neigh
[PATCH 10/15] batman-adv: ELP - send unicast ELP packets for throughput sampling
From: Antonio Quartulli In case of an unused wireless link, the mac80211 throughput estimation won't get updated further. Consequently, the reported throughput metric will become obsolete. With this patch unicast sampling is introduced by periodically sending unicast ELP packets to each neighbor on idle WiFi links. These sampling packets will fill an entire frame, so that the measurement is as reliable as possible Signed-off-by: Antonio Quartulli Signed-off-by: Marek Lindner --- net/batman-adv/bat_v_elp.c | 69 ++ net/batman-adv/main.h | 3 ++ 2 files changed, 72 insertions(+) diff --git a/net/batman-adv/bat_v_elp.c b/net/batman-adv/bat_v_elp.c index 8376730ebd69..3844e7efd0b0 100644 --- a/net/batman-adv/bat_v_elp.c +++ b/net/batman-adv/bat_v_elp.c @@ -165,6 +165,69 @@ void batadv_v_elp_throughput_metric_update(struct work_struct *work) } /** + * batadv_v_elp_wifi_neigh_probe - send link probing packets to a neighbour + * @neigh: the neighbour to probe + * + * Sends a predefined number of unicast wifi packets to a given neighbour in + * order to trigger the throughput estimation on this link by the RC algorithm. + * Packets are sent only if there there is not enough payload unicast traffic + * towards this neighbour.. + * + * Return: True on success and false in case of error during skb preparation. + */ +static bool +batadv_v_elp_wifi_neigh_probe(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); + unsigned long last_tx_diff; + struct sk_buff *skb; + int probe_len, i; + int elp_skb_len; + + /* this probing routine is for Wifi neighbours only */ + if (!batadv_is_wifi_netdev(hard_iface->net_dev)) + return true; + + /* probe the neighbor only if no unicast packets have been sent +* to it in the last 100 milliseconds: this is the rate control +* algorithm sampling interval (minstrel). In this way, if not +* enough traffic has been sent to the neighbor, batman-adv can +* generate 2 probe packets and push the RC algorithm to perform +* the sampling +*/ + last_tx_diff = jiffies_to_msecs(jiffies - neigh->bat_v.last_unicast_tx); + if (last_tx_diff <= BATADV_ELP_PROBE_MAX_TX_DIFF) + return true; + + probe_len = max_t(int, sizeof(struct batadv_elp_packet), + BATADV_ELP_MIN_PROBE_SIZE); + + for (i = 0; i < BATADV_ELP_PROBES_PER_NODE; i++) { + elp_skb_len = hard_iface->bat_v.elp_skb->len; + skb = skb_copy_expand(hard_iface->bat_v.elp_skb, 0, + probe_len - elp_skb_len, + GFP_ATOMIC); + if (!skb) + return false; + + /* Tell the skb to get as big as the allocated space (we want +* the packet to be exactly of that size to make the link +* throughput estimation effective. +*/ + skb_put(skb, probe_len - hard_iface->bat_v.elp_skb->len); + + batadv_dbg(BATADV_DBG_BATMAN, bat_priv, + "Sending unicast (probe) ELP packet on interface %s to %pM\n", + hard_iface->net_dev->name, neigh->addr); + + batadv_send_skb_packet(skb, hard_iface, neigh->addr); + } + + return true; +} + +/** * batadv_v_elp_periodic_work - ELP periodic task per interface * @work: work queue item * @@ -227,6 +290,12 @@ static void batadv_v_elp_periodic_work(struct work_struct *work) */ rcu_read_lock(); hlist_for_each_entry_rcu(hardif_neigh, &hard_iface->neigh_list, list) { + if (!batadv_v_elp_wifi_neigh_probe(hardif_neigh)) + /* if something goes wrong while probing, better to stop +* sending packets immediately and reschedule the task +*/ + break; + if (!kref_get_unless_zero(&hardif_neigh->refcount)) continue; diff --git a/net/batman-adv/main.h b/net/batman-adv/main.h index 5c68bf2618c7..878c35974845 100644 --- a/net/batman-adv/main.h +++ b/net/batman-adv/main.h @@ -63,6 +63,9 @@ /* B.A.T.M.A.N. V */ #define BATADV_THROUGHPUT_DEFAULT_VALUE 10 /* 1 Mbps */ +#define BATADV_ELP_PROBES_PER_NODE 2 +#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_OGM_MAX_ORIGDIFF 5 #define BATADV_OGM_MAX_AGE 64 -- 2.7.2
[PATCH 14/15] batman-adv: Start new development cycle
From: Simon Wunderlich Signed-off-by: Simon Wunderlich Signed-off-by: Antonio Quartulli --- net/batman-adv/main.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/batman-adv/main.h b/net/batman-adv/main.h index 878c35974845..db4533631834 100644 --- a/net/batman-adv/main.h +++ b/net/batman-adv/main.h @@ -24,7 +24,7 @@ #define BATADV_DRIVER_DEVICE "batman-adv" #ifndef BATADV_SOURCE_VERSION -#define BATADV_SOURCE_VERSION "2016.0" +#define BATADV_SOURCE_VERSION "2016.1" #endif /* B.A.T.M.A.N. parameters */ -- 2.7.2
[PATCH 15/15] MAINTAINERS: Add patchwork URL for BATMAN ADVANCED
From: Sven Eckelmann Signed-off-by: Sven Eckelmann Signed-off-by: Antonio Quartulli --- MAINTAINERS | 1 + 1 file changed, 1 insertion(+) diff --git a/MAINTAINERS b/MAINTAINERS index 27393cff1707..4fe223aa154d 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2152,6 +2152,7 @@ M:Simon Wunderlich M: Antonio Quartulli L: b.a.t.m@lists.open-mesh.org W: https://www.open-mesh.org/ +Q: https://patchwork.open-mesh.org/project/batman/list/ S: Maintained F: net/batman-adv/ -- 2.7.2
[PATCH 13/15] batman-adv: B.A.T.M.A.N. V - implement bat_neigh_print API
From: Linus Luessing Lists all neighbours detected by the Echo Locating Protocol (ELP) and their throughput metric. Initially Developed by Linus during a 6 months trainee study period in Ascom (Switzerland) AG. Signed-off-by: Linus Luessing Signed-off-by: Marek Lindner Signed-off-by: Antonio Quartulli --- net/batman-adv/bat_v.c | 55 ++ 1 file changed, 55 insertions(+) diff --git a/net/batman-adv/bat_v.c b/net/batman-adv/bat_v.c index a90117c9a861..3315b9a598af 100644 --- a/net/batman-adv/bat_v.c +++ b/net/batman-adv/bat_v.c @@ -118,6 +118,60 @@ batadv_v_orig_print_neigh(struct batadv_orig_node *orig_node, } /** + * batadv_v_hardif_neigh_print - print a single ELP neighbour node + * @seq: neighbour table seq_file struct + * @hardif_neigh: hardif neighbour information + */ +static void +batadv_v_hardif_neigh_print(struct seq_file *seq, + struct batadv_hardif_neigh_node *hardif_neigh) +{ + int last_secs, last_msecs; + u32 throughput; + + last_secs = jiffies_to_msecs(jiffies - hardif_neigh->last_seen) / 1000; + last_msecs = jiffies_to_msecs(jiffies - hardif_neigh->last_seen) % 1000; + throughput = ewma_throughput_read(&hardif_neigh->bat_v.throughput); + + seq_printf(seq, "%pM %4i.%03is (%9u.%1u) [%10s]\n", + hardif_neigh->addr, last_secs, last_msecs, throughput / 10, + throughput % 10, hardif_neigh->if_incoming->net_dev->name); +} + +/** + * batadv_v_neigh_print - print the single hop neighbour list + * @bat_priv: the bat priv with all the soft interface information + * @seq: neighbour table seq_file struct + */ +static void batadv_v_neigh_print(struct batadv_priv *bat_priv, +struct seq_file *seq) +{ + struct net_device *net_dev = (struct net_device *)seq->private; + struct batadv_hardif_neigh_node *hardif_neigh; + struct batadv_hard_iface *hard_iface; + int batman_count = 0; + + seq_printf(seq, " %-15s %s (%11s) [%10s]\n", "Neighbor", + "last-seen", "throughput", "IF"); + + rcu_read_lock(); + list_for_each_entry_rcu(hard_iface, &batadv_hardif_list, list) { + if (hard_iface->soft_iface != net_dev) + continue; + + hlist_for_each_entry_rcu(hardif_neigh, +&hard_iface->neigh_list, list) { + batadv_v_hardif_neigh_print(seq, hardif_neigh); + batman_count++; + } + } + rcu_read_unlock(); + + if (batman_count == 0) + seq_puts(seq, "No batman nodes in range ...\n"); +} + +/** * batadv_v_orig_print - print the originator table * @bat_priv: the bat priv with all the soft interface information * @seq: debugfs table seq_file struct @@ -230,6 +284,7 @@ static struct batadv_algo_ops batadv_batman_v __read_mostly = { .bat_orig_print = batadv_v_orig_print, .bat_neigh_cmp = batadv_v_neigh_cmp, .bat_neigh_is_similar_or_better = batadv_v_neigh_is_sob, + .bat_neigh_print = batadv_v_neigh_print, }; /** -- 2.7.2
[PATCH 04/15] batman-adv: ELP - adding sysfs parameter for elp interval
From: Linus Luessing This parameter can be set individually on each interface and allows the configuration of the elp interval for the link quality measurements during runtime. Usually it is desirable to set it to a higher (= slower) value on interfaces which have a more static characteristic (e.g. wired interfaces) or very dense neighbourhoods to reduce overhead. Developed by Linus during a 6 months trainee study period in Ascom (Switzerland) AG. Signed-off-by: Linus Luessing Signed-off-by: Marek Lindner [anto...@open-mesh.com: respin on top of the latest master] Signed-off-by: Antonio Quartulli --- Documentation/ABI/testing/sysfs-class-net-batman-adv | 8 +++- net/batman-adv/sysfs.c | 7 +++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/Documentation/ABI/testing/sysfs-class-net-batman-adv b/Documentation/ABI/testing/sysfs-class-net-batman-adv index 7f34a95bb963..aea78db983bc 100644 --- a/Documentation/ABI/testing/sysfs-class-net-batman-adv +++ b/Documentation/ABI/testing/sysfs-class-net-batman-adv @@ -1,4 +1,11 @@ +What: /sys/class/net//batman-adv/elp_interval +Date: Feb 2014 +Contact:Linus Lüssing +Description: +Defines the interval in milliseconds in which batman +sends its probing packets for link quality measurements. + What: /sys/class/net//batman-adv/iface_status Date: May 2010 Contact:Marek Lindner @@ -12,4 +19,3 @@ Description: The /sys/class/net//batman-adv/mesh_iface file displays the batman mesh interface this currently is associated with. - diff --git a/net/batman-adv/sysfs.c b/net/batman-adv/sysfs.c index d3f69d5e79d9..e86014332e1c 100644 --- a/net/batman-adv/sysfs.c +++ b/net/batman-adv/sysfs.c @@ -920,10 +920,17 @@ static ssize_t batadv_show_iface_status(struct kobject *kobj, static BATADV_ATTR(mesh_iface, S_IRUGO | S_IWUSR, batadv_show_mesh_iface, batadv_store_mesh_iface); static BATADV_ATTR(iface_status, S_IRUGO, batadv_show_iface_status, NULL); +#ifdef CONFIG_BATMAN_ADV_BATMAN_V +BATADV_ATTR_HIF_UINT(elp_interval, bat_v.elp_interval, S_IRUGO | S_IWUSR, +2 * BATADV_JITTER, INT_MAX, NULL); +#endif static struct batadv_attribute *batadv_batman_attrs[] = { &batadv_attr_mesh_iface, &batadv_attr_iface_status, +#ifdef CONFIG_BATMAN_ADV_BATMAN_V + &batadv_attr_elp_interval, +#endif NULL, }; -- 2.7.2
[PATCH 05/15] batman-adv: OGMv2 - add basic infrastructure
From: Antonio Quartulli This is the initial implementation of the new OGM protocol (version 2). It has been designed to work on top of the newly added ELP. In the previous version the OGM protocol was used to both measure link qualities and flood the network with the metric information. In this version the protocol is in charge of the latter task only, leaving the former to ELP. This means being able to decouple the interval used by the neighbor discovery from the OGM broadcasting, which revealed to be costly in dense networks and needed to be relaxed so leading to a less responsive routing protocol. Signed-off-by: Antonio Quartulli Signed-off-by: Marek Lindner --- net/batman-adv/Makefile| 1 + net/batman-adv/bat_algo.h | 13 +++ net/batman-adv/bat_v.c | 53 - net/batman-adv/bat_v_ogm.c | 279 + net/batman-adv/bat_v_ogm.h | 32 ++ net/batman-adv/main.c | 6 + net/batman-adv/main.h | 1 + net/batman-adv/packet.h| 29 + net/batman-adv/types.h | 18 +++ 9 files changed, 428 insertions(+), 4 deletions(-) create mode 100644 net/batman-adv/bat_v_ogm.c create mode 100644 net/batman-adv/bat_v_ogm.h diff --git a/net/batman-adv/Makefile b/net/batman-adv/Makefile index ca51686e9f72..797cf2fc88c1 100644 --- a/net/batman-adv/Makefile +++ b/net/batman-adv/Makefile @@ -20,6 +20,7 @@ obj-$(CONFIG_BATMAN_ADV) += batman-adv.o batman-adv-y += bat_iv_ogm.o batman-adv-$(CONFIG_BATMAN_ADV_BATMAN_V) += bat_v.o batman-adv-$(CONFIG_BATMAN_ADV_BATMAN_V) += bat_v_elp.o +batman-adv-$(CONFIG_BATMAN_ADV_BATMAN_V) += bat_v_ogm.o batman-adv-y += bitarray.o batman-adv-$(CONFIG_BATMAN_ADV_BLA) += bridge_loop_avoidance.o batman-adv-$(CONFIG_DEBUG_FS) += debugfs.o diff --git a/net/batman-adv/bat_algo.h b/net/batman-adv/bat_algo.h index a4e994e26da1..03dafd33d23b 100644 --- a/net/batman-adv/bat_algo.h +++ b/net/batman-adv/bat_algo.h @@ -18,11 +18,15 @@ #ifndef _NET_BATMAN_ADV_BAT_ALGO_H_ #define _NET_BATMAN_ADV_BAT_ALGO_H_ +struct batadv_priv; + int batadv_iv_init(void); #ifdef CONFIG_BATMAN_ADV_BATMAN_V int batadv_v_init(void); +int batadv_v_mesh_init(struct batadv_priv *bat_priv); +void batadv_v_mesh_free(struct batadv_priv *bat_priv); #else @@ -31,6 +35,15 @@ static inline int batadv_v_init(void) return 0; } +static inline int batadv_v_mesh_init(struct batadv_priv *bat_priv) +{ + return 0; +} + +static inline void batadv_v_mesh_free(struct batadv_priv *bat_priv) +{ +} + #endif /* CONFIG_BATMAN_ADV_BATMAN_V */ #endif /* _NET_BATMAN_ADV_BAT_ALGO_H_ */ diff --git a/net/batman-adv/bat_v.c b/net/batman-adv/bat_v.c index 0fea894855ff..b90a4dfe8ba6 100644 --- a/net/batman-adv/bat_v.c +++ b/net/batman-adv/bat_v.c @@ -22,11 +22,22 @@ #include #include "bat_v_elp.h" +#include "bat_v_ogm.h" #include "packet.h" static int batadv_v_iface_enable(struct batadv_hard_iface *hard_iface) { - return batadv_v_elp_iface_enable(hard_iface); + int ret; + + ret = batadv_v_elp_iface_enable(hard_iface); + if (ret < 0) + return ret; + + ret = batadv_v_ogm_iface_enable(hard_iface); + if (ret < 0) + batadv_v_elp_iface_disable(hard_iface); + + return ret; } static void batadv_v_iface_disable(struct batadv_hard_iface *hard_iface) @@ -41,6 +52,7 @@ static void batadv_v_iface_update_mac(struct batadv_hard_iface *hard_iface) static void batadv_v_primary_iface_set(struct batadv_hard_iface *hard_iface) { batadv_v_elp_primary_iface_set(hard_iface); + batadv_v_ogm_primary_iface_set(hard_iface); } static void @@ -69,6 +81,27 @@ static struct batadv_algo_ops batadv_batman_v __read_mostly = { }; /** + * batadv_v_mesh_init - initialize the B.A.T.M.A.N. V private resources for a + * mesh + * @bat_priv: the object representing the mesh interface to initialise + * + * Return: 0 on success or a negative error code otherwise + */ +int batadv_v_mesh_init(struct batadv_priv *bat_priv) +{ + return batadv_v_ogm_init(bat_priv); +} + +/** + * batadv_v_mesh_free - free the B.A.T.M.A.N. V private resources for a mesh + * @bat_priv: the object representing the mesh interface to free + */ +void batadv_v_mesh_free(struct batadv_priv *bat_priv) +{ + batadv_v_ogm_free(bat_priv); +} + +/** * batadv_v_init - B.A.T.M.A.N. V initialization function * * Description: Takes care of initializing all the subcomponents. @@ -86,10 +119,22 @@ int __init batadv_v_init(void) if (ret < 0) return ret; - ret = batadv_algo_register(&batadv_batman_v); - + ret = batadv_recv_handler_register(BATADV_OGM2, + batadv_v_ogm_packet_recv); if (ret < 0) - batadv_recv_handler_unregister(BATADV_ELP); + goto elp_unregister; + + ret = batadv_algo_register(&batadv_batman_v); +
[PATCH 08/15] batman-adv: keep track of when unicast packets are sent
From: Antonio Quartulli To enable ELP to send probing packets over wireless links only if needed, batman-adv must keep track of the last time it sent a unicast packet towards every neighbour. For this purpose a 2 main changes are introduced: 1) a new member of the elp_neigh_node structure stores the last time a unicast packet was sent towards this neighbour; 2) a wrapper function for sending unicast packets is implemented. This function will simply update the member describe din point 1) and then forward the packet to the real sending routine. Point 2) implies that any code-path leading to a unicast sending now has to use the new wrapper. Signed-off-by: Antonio Quartulli Signed-off-by: Marek Lindner --- net/batman-adv/bat_iv_ogm.c| 2 +- net/batman-adv/bat_v_elp.c | 2 +- net/batman-adv/bat_v_ogm.c | 2 +- net/batman-adv/distributed-arp-table.c | 4 +-- net/batman-adv/fragmentation.c | 8 ++--- net/batman-adv/icmp_socket.c | 2 +- net/batman-adv/network-coding.c| 22 +++--- net/batman-adv/send.c | 55 +- net/batman-adv/send.h | 10 +-- net/batman-adv/types.h | 2 ++ 10 files changed, 75 insertions(+), 34 deletions(-) diff --git a/net/batman-adv/bat_iv_ogm.c b/net/batman-adv/bat_iv_ogm.c index 5651e33ca6bd..cb2d1b9b0340 100644 --- a/net/batman-adv/bat_iv_ogm.c +++ b/net/batman-adv/bat_iv_ogm.c @@ -478,7 +478,7 @@ static void batadv_iv_ogm_send_to_if(struct batadv_forw_packet *forw_packet, batadv_inc_counter(bat_priv, BATADV_CNT_MGMT_TX); batadv_add_counter(bat_priv, BATADV_CNT_MGMT_TX_BYTES, skb->len + ETH_HLEN); - batadv_send_skb_packet(skb, hard_iface, batadv_broadcast_addr); + batadv_send_broadcast_skb(skb, hard_iface); } } diff --git a/net/batman-adv/bat_v_elp.c b/net/batman-adv/bat_v_elp.c index fac5aee7ce05..1e4d13cc267f 100644 --- a/net/batman-adv/bat_v_elp.c +++ b/net/batman-adv/bat_v_elp.c @@ -104,7 +104,7 @@ static void batadv_v_elp_periodic_work(struct work_struct *work) hard_iface->net_dev->name, atomic_read(&hard_iface->bat_v.elp_seqno)); - batadv_send_skb_packet(skb, hard_iface, batadv_broadcast_addr); + batadv_send_broadcast_skb(skb, hard_iface); atomic_inc(&hard_iface->bat_v.elp_seqno); diff --git a/net/batman-adv/bat_v_ogm.c b/net/batman-adv/bat_v_ogm.c index 22dda0e079a5..c8000962a266 100644 --- a/net/batman-adv/bat_v_ogm.c +++ b/net/batman-adv/bat_v_ogm.c @@ -120,7 +120,7 @@ static void batadv_v_ogm_send_to_if(struct sk_buff *skb, batadv_add_counter(bat_priv, BATADV_CNT_MGMT_TX_BYTES, skb->len + ETH_HLEN); - batadv_send_skb_packet(skb, hard_iface, batadv_broadcast_addr); + batadv_send_broadcast_skb(skb, hard_iface); } /** diff --git a/net/batman-adv/distributed-arp-table.c b/net/batman-adv/distributed-arp-table.c index 4c9b69d465a6..e96d7c745b4a 100644 --- a/net/batman-adv/distributed-arp-table.c +++ b/net/batman-adv/distributed-arp-table.c @@ -654,9 +654,7 @@ static bool batadv_dat_send_data(struct batadv_priv *bat_priv, goto free_neigh; } - send_status = batadv_send_skb_packet(tmp_skb, -neigh_node->if_incoming, -neigh_node->addr); + send_status = batadv_send_unicast_skb(tmp_skb, neigh_node); if (send_status == NET_XMIT_SUCCESS) { /* count the sent packet */ switch (packet_subtype) { diff --git a/net/batman-adv/fragmentation.c b/net/batman-adv/fragmentation.c index adb9c3989add..e6956d0746a2 100644 --- a/net/batman-adv/fragmentation.c +++ b/net/batman-adv/fragmentation.c @@ -378,8 +378,7 @@ bool batadv_frag_skb_fwd(struct sk_buff *skb, skb->len + ETH_HLEN); packet->ttl--; - batadv_send_skb_packet(skb, neigh_node->if_incoming, - neigh_node->addr); + batadv_send_unicast_skb(skb, neigh_node); ret = true; } @@ -486,8 +485,7 @@ bool batadv_frag_send_packet(struct sk_buff *skb, batadv_inc_counter(bat_priv, BATADV_CNT_FRAG_TX); batadv_add_counter(bat_priv, BATADV_CNT_FRAG_TX_BYTES, skb_fragment->len + ETH_HLEN); - batadv_send_skb_packet(skb_fragment, neigh_node->if_incoming, - neigh_node->addr); + batadv_send_unicast_skb(skb_fragment, neigh_node); frag_header.no++; /* The initial check in this functi
[PATCH 03/15] batman-adv: ELP - creating neighbor structures
From: Linus Luessing Initially developed by Linus during a 6 months trainee study period in Ascom (Switzerland) AG. Signed-off-by: Linus Luessing Signed-off-by: Marek Lindner Signed-off-by: Antonio Quartulli --- net/batman-adv/bat_v.c | 23 ++- net/batman-adv/bat_v_elp.c | 152 + net/batman-adv/bat_v_elp.h | 4 ++ net/batman-adv/main.h | 3 + net/batman-adv/types.h | 33 ++ 5 files changed, 214 insertions(+), 1 deletion(-) diff --git a/net/batman-adv/bat_v.c b/net/batman-adv/bat_v.c index 01327f627a08..0fea894855ff 100644 --- a/net/batman-adv/bat_v.c +++ b/net/batman-adv/bat_v.c @@ -22,6 +22,7 @@ #include #include "bat_v_elp.h" +#include "packet.h" static int batadv_v_iface_enable(struct batadv_hard_iface *hard_iface) { @@ -42,6 +43,12 @@ static void batadv_v_primary_iface_set(struct batadv_hard_iface *hard_iface) batadv_v_elp_primary_iface_set(hard_iface); } +static void +batadv_v_hardif_neigh_init(struct batadv_hardif_neigh_node *hardif_neigh) +{ + ewma_throughput_init(&hardif_neigh->bat_v.throughput); +} + static void batadv_v_ogm_schedule(struct batadv_hard_iface *hard_iface) { } @@ -56,6 +63,7 @@ static struct batadv_algo_ops batadv_batman_v __read_mostly = { .bat_iface_disable = batadv_v_iface_disable, .bat_iface_update_mac = batadv_v_iface_update_mac, .bat_primary_iface_set = batadv_v_primary_iface_set, + .bat_hardif_neigh_init = batadv_v_hardif_neigh_init, .bat_ogm_emit = batadv_v_ogm_emit, .bat_ogm_schedule = batadv_v_ogm_schedule, }; @@ -70,5 +78,18 @@ static struct batadv_algo_ops batadv_batman_v __read_mostly = { */ int __init batadv_v_init(void) { - return batadv_algo_register(&batadv_batman_v); + int ret; + + /* B.A.T.M.A.N. V echo location protocol packet */ + ret = batadv_recv_handler_register(BATADV_ELP, + batadv_v_elp_packet_recv); + if (ret < 0) + return ret; + + ret = batadv_algo_register(&batadv_batman_v); + + if (ret < 0) + batadv_recv_handler_unregister(BATADV_ELP); + + return ret; } diff --git a/net/batman-adv/bat_v_elp.c b/net/batman-adv/bat_v_elp.c index bc6e046c614c..dac88fad2697 100644 --- a/net/batman-adv/bat_v_elp.c +++ b/net/batman-adv/bat_v_elp.c @@ -38,7 +38,10 @@ #include "bat_algo.h" #include "hard-interface.h" +#include "hash.h" +#include "originator.h" #include "packet.h" +#include "routing.h" #include "send.h" /** @@ -191,3 +194,152 @@ void batadv_v_elp_primary_iface_set(struct batadv_hard_iface *primary_iface) } rcu_read_unlock(); } + +/** + * batadv_v_ogm_orig_get - retrieve and possibly create an originator node + * @bat_priv: the bat priv with all the soft interface information + * @addr: the address of the originator + * + * Return: the orig_node corresponding to the specified address. If such object + * does not exist it is allocated here. In case of allocation failure returns + * NULL. + */ +static struct batadv_orig_node * +batadv_v_ogm_orig_get(struct batadv_priv *bat_priv, + const u8 *addr) +{ + struct batadv_orig_node *orig_node; + int hash_added; + + orig_node = batadv_orig_hash_find(bat_priv, addr); + if (orig_node) + return orig_node; + + orig_node = batadv_orig_node_new(bat_priv, addr); + if (!orig_node) + return NULL; + + hash_added = batadv_hash_add(bat_priv->orig_hash, batadv_compare_orig, +batadv_choose_orig, orig_node, +&orig_node->hash_entry); + if (hash_added != 0) { + /* orig_node->refcounter is initialised to 2 by +* batadv_orig_node_new() +*/ + batadv_orig_node_put(orig_node); + batadv_orig_node_put(orig_node); + orig_node = NULL; + } + + return orig_node; +} + +/** + * batadv_v_elp_neigh_update - update an ELP neighbour node + * @bat_priv: the bat priv with all the soft interface information + * @neigh_addr: the neighbour interface address + * @if_incoming: the interface the packet was received through + * @elp_packet: the received ELP packet + * + * Updates the ELP neighbour node state with the data received within the new + * ELP packet. + */ +static void batadv_v_elp_neigh_update(struct batadv_priv *bat_priv, + u8 *neigh_addr, + struct batadv_hard_iface *if_incoming, + struct batadv_elp_packet *elp_packet) + +{ + struct batadv_neigh_node *neigh; + struct batadv_orig_node *orig_neigh; + struct batadv_hardif_neigh_nod
[PATCH 02/15] batman-adv: ELP - adding basic infrastructure
From: Linus Luessing The B.A.T.M.A.N. protocol originally only used a single message type (called OGM) to determine the link qualities to the direct neighbors and spreading these link quality information through the whole mesh. This procedure is summarized on the BATMAN concept page and explained in details in the RFC draft published in 2008. This approach was chosen for its simplicity during the protocol design phase and the implementation. However, it also bears some drawbacks: * Wireless interfaces usually come with some packet loss, therefore a higher broadcast rate is desirable to allow a fast reaction on flaky connections. Other interfaces of the same host might be connected to Ethernet LANs / VPNs / etc which rarely exhibit packet loss would benefit from a lower broadcast rate to reduce overhead. * It generally is more desirable to detect local link quality changes at a faster rate than propagating all these changes through the entire mesh (the far end of the mesh does not need to care about local link quality changes that much). Other optimizations strategies, like reducing overhead, might be possible if OGMs weren't used for all tasks in the mesh at the same time. As a result detecting local link qualities shall be handled by an independent message type, ELP, whereas the OGM message type remains responsible for flooding the mesh with these link quality information and determining the overall path transmit qualities. Developed by Linus during a 6 months trainee study period in Ascom (Switzerland) AG. Signed-off-by: Linus Luessing Signed-off-by: Marek Lindner Signed-off-by: Antonio Quartulli --- net/batman-adv/Kconfig | 14 net/batman-adv/Makefile| 2 + net/batman-adv/bat_algo.h | 15 +++- net/batman-adv/bat_v.c | 74 + net/batman-adv/bat_v_elp.c | 193 + net/batman-adv/bat_v_elp.h | 27 +++ net/batman-adv/main.c | 1 + net/batman-adv/packet.h| 20 + net/batman-adv/types.h | 18 + 9 files changed, 363 insertions(+), 1 deletion(-) create mode 100644 net/batman-adv/bat_v.c create mode 100644 net/batman-adv/bat_v_elp.c create mode 100644 net/batman-adv/bat_v_elp.h diff --git a/net/batman-adv/Kconfig b/net/batman-adv/Kconfig index 2dd40e5ea030..5c148a8489da 100644 --- a/net/batman-adv/Kconfig +++ b/net/batman-adv/Kconfig @@ -15,6 +15,20 @@ config BATMAN_ADV https://www.open-mesh.org/ for more information and user space tools. +config BATMAN_ADV_BATMAN_V + bool "B.A.T.M.A.N. V protocol (experimental)" + depends on BATMAN_ADV + default n + help + This option enables the B.A.T.M.A.N. V protocol, the successor + of the currently used B.A.T.M.A.N. IV protocol. The main + changes include splitting of the OGM protocol into a neighbor + discovery protocol (Echo Location Protocol, ELP) and a new OGM + Protocol OGMv2 for flooding protocol information through the + network, as well as a throughput based metric. + B.A.T.M.A.N. V is currently considered experimental and not + compatible to B.A.T.M.A.N. IV networks. + config BATMAN_ADV_BLA bool "Bridge Loop Avoidance" depends on BATMAN_ADV && INET diff --git a/net/batman-adv/Makefile b/net/batman-adv/Makefile index 207e2af316c7..ca51686e9f72 100644 --- a/net/batman-adv/Makefile +++ b/net/batman-adv/Makefile @@ -18,6 +18,8 @@ obj-$(CONFIG_BATMAN_ADV) += batman-adv.o batman-adv-y += bat_iv_ogm.o +batman-adv-$(CONFIG_BATMAN_ADV_BATMAN_V) += bat_v.o +batman-adv-$(CONFIG_BATMAN_ADV_BATMAN_V) += bat_v_elp.o batman-adv-y += bitarray.o batman-adv-$(CONFIG_BATMAN_ADV_BLA) += bridge_loop_avoidance.o batman-adv-$(CONFIG_DEBUG_FS) += debugfs.o diff --git a/net/batman-adv/bat_algo.h b/net/batman-adv/bat_algo.h index a7485d676088..a4e994e26da1 100644 --- a/net/batman-adv/bat_algo.h +++ b/net/batman-adv/bat_algo.h @@ -1,6 +1,6 @@ /* Copyright (C) 2011-2016 B.A.T.M.A.N. contributors: * - * Marek Lindner + * Marek Lindner, 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 @@ -20,4 +20,17 @@ int batadv_iv_init(void); +#ifdef CONFIG_BATMAN_ADV_BATMAN_V + +int batadv_v_init(void); + +#else + +static inline int batadv_v_init(void) +{ + return 0; +} + +#endif /* CONFIG_BATMAN_ADV_BATMAN_V */ + #endif /* _NET_BATMAN_ADV_BAT_ALGO_H_ */ diff --git a/net/batman-adv/bat_v.c b/net/batman-adv/bat_v.c new file mode 100644 index ..01327f627a08 --- /dev/null +++ b/net/batman-adv/bat_v.c @@ -0,0 +1,74 @@ +/* Copyright (C) 2013-2016 B.A.T.M.A.N. contributors: + * + * Linus Lüssing, Marek Lindner + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General P
[PATCH 06/15] batman-adv: OGMv2 - implement originators logic
From: Antonio Quartulli Add the support for recognising new originators in the network and rebroadcast their OGMs. Signed-off-by: Antonio Quartulli Signed-off-by: Marek Lindner --- net/batman-adv/bat_v_elp.c | 41 +--- net/batman-adv/bat_v_ogm.c | 556 - net/batman-adv/bat_v_ogm.h | 4 + net/batman-adv/main.h | 2 + net/batman-adv/types.h | 4 + 5 files changed, 566 insertions(+), 41 deletions(-) diff --git a/net/batman-adv/bat_v_elp.c b/net/batman-adv/bat_v_elp.c index dac88fad2697..fac5aee7ce05 100644 --- a/net/batman-adv/bat_v_elp.c +++ b/net/batman-adv/bat_v_elp.c @@ -37,8 +37,8 @@ #include #include "bat_algo.h" +#include "bat_v_ogm.h" #include "hard-interface.h" -#include "hash.h" #include "originator.h" #include "packet.h" #include "routing.h" @@ -196,45 +196,6 @@ void batadv_v_elp_primary_iface_set(struct batadv_hard_iface *primary_iface) } /** - * batadv_v_ogm_orig_get - retrieve and possibly create an originator node - * @bat_priv: the bat priv with all the soft interface information - * @addr: the address of the originator - * - * Return: the orig_node corresponding to the specified address. If such object - * does not exist it is allocated here. In case of allocation failure returns - * NULL. - */ -static struct batadv_orig_node * -batadv_v_ogm_orig_get(struct batadv_priv *bat_priv, - const u8 *addr) -{ - struct batadv_orig_node *orig_node; - int hash_added; - - orig_node = batadv_orig_hash_find(bat_priv, addr); - if (orig_node) - return orig_node; - - orig_node = batadv_orig_node_new(bat_priv, addr); - if (!orig_node) - return NULL; - - hash_added = batadv_hash_add(bat_priv->orig_hash, batadv_compare_orig, -batadv_choose_orig, orig_node, -&orig_node->hash_entry); - if (hash_added != 0) { - /* orig_node->refcounter is initialised to 2 by -* batadv_orig_node_new() -*/ - batadv_orig_node_put(orig_node); - batadv_orig_node_put(orig_node); - orig_node = NULL; - } - - return orig_node; -} - -/** * batadv_v_elp_neigh_update - update an ELP neighbour node * @bat_priv: the bat priv with all the soft interface information * @neigh_addr: the neighbour interface address diff --git a/net/batman-adv/bat_v_ogm.c b/net/batman-adv/bat_v_ogm.c index 23932f9b85ec..22dda0e079a5 100644 --- a/net/batman-adv/bat_v_ogm.c +++ b/net/batman-adv/bat_v_ogm.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -38,12 +39,52 @@ #include #include "hard-interface.h" +#include "hash.h" +#include "originator.h" #include "packet.h" #include "routing.h" #include "send.h" #include "translation-table.h" /** + * batadv_v_ogm_orig_get - retrieve and possibly create an originator node + * @bat_priv: the bat priv with all the soft interface information + * @addr: the address of the originator + * + * Return: the orig_node corresponding to the specified address. If such object + * does not exist it is allocated here. In case of allocation failure returns + * NULL. + */ +struct batadv_orig_node *batadv_v_ogm_orig_get(struct batadv_priv *bat_priv, + const u8 *addr) +{ + struct batadv_orig_node *orig_node; + int hash_added; + + orig_node = batadv_orig_hash_find(bat_priv, addr); + if (orig_node) + return orig_node; + + orig_node = batadv_orig_node_new(bat_priv, addr); + if (!orig_node) + return NULL; + + hash_added = batadv_hash_add(bat_priv->orig_hash, batadv_compare_orig, +batadv_choose_orig, orig_node, +&orig_node->hash_entry); + if (hash_added != 0) { + /* orig_node->refcounter is initialised to 2 by +* batadv_orig_node_new() +*/ + batadv_orig_node_put(orig_node); + batadv_orig_node_put(orig_node); + orig_node = NULL; + } + + return orig_node; +} + +/** * batadv_v_ogm_start_timer - restart the OGM sending timer * @bat_priv: the bat priv with all the soft interface information */ @@ -193,6 +234,500 @@ void batadv_v_ogm_primary_iface_set(struct batadv_hard_iface *primary_iface) } /** + * batadv_v_ogm_orig_update - update the originator status based on the received + * OGM + * @bat_priv: the bat priv with all the soft interface information + * @orig_node: the originator to update + * @neigh_node: the neighbour the OGM has been received from (to update) + * @ogm2: the
[PATCH 09/15] batman-adv: ELP - compute the metric based on the estimated throughput
From: Antonio Quartulli In case of wireless interface retrieve the throughput by querying cfg80211. To perform this call a separate work must be scheduled because the function may sleep and this is not allowed within an RCU protected context (RCU in this case is used to iterate over all the neighbours). Use ethtool to retrieve information about an Ethernet link like HALF/FULL_DUPLEX and advertised bandwidth (e.g. 100/10Mbps). The metric is updated each time a new ELP packet is sent, this way it is possible to timely react to a metric variation which can imply (for example) a neighbour disconnection. Signed-off-by: Antonio Quartulli Signed-off-by: Marek Lindner --- net/batman-adv/Kconfig | 2 +- net/batman-adv/bat_v.c | 3 + net/batman-adv/bat_v_elp.c | 140 + net/batman-adv/bat_v_elp.h | 2 + net/batman-adv/bat_v_ogm.c | 2 +- net/batman-adv/main.h | 1 + net/batman-adv/types.h | 16 ++ 7 files changed, 164 insertions(+), 2 deletions(-) diff --git a/net/batman-adv/Kconfig b/net/batman-adv/Kconfig index 5c148a8489da..e651dc927bfd 100644 --- a/net/batman-adv/Kconfig +++ b/net/batman-adv/Kconfig @@ -17,7 +17,7 @@ config BATMAN_ADV config BATMAN_ADV_BATMAN_V bool "B.A.T.M.A.N. V protocol (experimental)" - depends on BATMAN_ADV + depends on BATMAN_ADV && CFG80211 default n help This option enables the B.A.T.M.A.N. V protocol, the successor diff --git a/net/batman-adv/bat_v.c b/net/batman-adv/bat_v.c index d9cb5c4922c1..ff31f2af9cfe 100644 --- a/net/batman-adv/bat_v.c +++ b/net/batman-adv/bat_v.c @@ -21,6 +21,7 @@ #include #include #include +#include #include "bat_v_elp.h" #include "bat_v_ogm.h" @@ -65,6 +66,8 @@ static void batadv_v_hardif_neigh_init(struct batadv_hardif_neigh_node *hardif_neigh) { ewma_throughput_init(&hardif_neigh->bat_v.throughput); + INIT_WORK(&hardif_neigh->bat_v.metric_work, + batadv_v_elp_throughput_metric_update); } static void batadv_v_ogm_schedule(struct batadv_hard_iface *hard_iface) diff --git a/net/batman-adv/bat_v_elp.c b/net/batman-adv/bat_v_elp.c index 1e4d13cc267f..8376730ebd69 100644 --- a/net/batman-adv/bat_v_elp.c +++ b/net/batman-adv/bat_v_elp.c @@ -22,19 +22,23 @@ #include #include #include +#include #include #include #include #include +#include #include #include #include #include +#include #include #include #include #include #include +#include #include "bat_algo.h" #include "bat_v_ogm.h" @@ -60,6 +64,107 @@ static void batadv_v_elp_start_timer(struct batadv_hard_iface *hard_iface) } /** + * batadv_v_elp_get_throughput - get the throughput towards a neighbour + * @neigh: the neighbour for which the throughput has to be obtained + * + * Return: The throughput towards the given neighbour in multiples of 100kpbs + * (a value of '1' equals to 0.1Mbps, '10' equals 1Mbps, etc). + */ +static u32 batadv_v_elp_get_throughput(struct batadv_hardif_neigh_node *neigh) +{ + struct batadv_hard_iface *hard_iface = neigh->if_incoming; + struct ethtool_link_ksettings link_settings; + struct station_info sinfo; + u32 throughput; + int ret; + + /* if the user specified a customised value for this interface, then +* return it directly +*/ + throughput = atomic_read(&hard_iface->bat_v.throughput_override); + if (throughput != 0) + return throughput; + + /* if this is a wireless device, then ask its throughput through +* cfg80211 API +*/ + if (batadv_is_wifi_netdev(hard_iface->net_dev)) { + if (hard_iface->net_dev->ieee80211_ptr) { + ret = cfg80211_get_station(hard_iface->net_dev, + neigh->addr, &sinfo); + if (ret == -ENOENT) { + /* Node is not associated anymore! It would be +* possible to delete this neighbor. For now set +* the throughput metric to 0. +*/ + return 0; + } + if (!ret) + return sinfo.expected_throughput / 100; + } + + /* unsupported WiFi driver version */ + goto default_throughput; + } + + /* if not a wifi interface, check if this device provides data via +* ethtool (e.g. an Ethernet adapter) +*/ + memset(&link_settings, 0, sizeof(link_settings)); + rtnl_lock(); + ret = __ethtool_get_link_ksettings(hard_iface->net_dev, &link_settings); + rtnl_unlock(); + if (ret ==
[PATCH 01/15] batman-adv: Add hard_iface specific sysfs wrapper macros for UINT
From: Linus Luessing This allows us to easily add a sysfs parameter for an unsigned int later, which is not for a batman mesh interface (e.g. bat0), but for a common interface instead. It allows reading and writing an atomic_t in hard_iface (instead of bat_priv compared to the mesh variant). Developed by Linus during a 6 months trainee study period in Ascom (Switzerland) AG. Signed-off-by: Linus Luessing Signed-off-by: Marek Lindner [anto...@open-mesh.com: rename functions and move macros] Signed-off-by: Antonio Quartulli --- net/batman-adv/sysfs.c | 49 + 1 file changed, 49 insertions(+) diff --git a/net/batman-adv/sysfs.c b/net/batman-adv/sysfs.c index 4d70d4413e40..d3f69d5e79d9 100644 --- a/net/batman-adv/sysfs.c +++ b/net/batman-adv/sysfs.c @@ -242,6 +242,55 @@ ssize_t batadv_show_vlan_##_name(struct kobject *kobj, \ static BATADV_ATTR_VLAN(_name, _mode, batadv_show_vlan_##_name, \ batadv_store_vlan_##_name) +#define BATADV_ATTR_HIF_STORE_UINT(_name, _var, _min, _max, _post_func) \ +ssize_t batadv_store_##_name(struct kobject *kobj, \ +struct attribute *attr, char *buff,\ +size_t count) \ +{ \ + struct net_device *net_dev = batadv_kobj_to_netdev(kobj); \ + struct batadv_hard_iface *hard_iface; \ + ssize_t length; \ + \ + hard_iface = batadv_hardif_get_by_netdev(net_dev); \ + if (!hard_iface)\ + return 0; \ + \ + length = __batadv_store_uint_attr(buff, count, _min, _max, \ + _post_func, attr, \ + &hard_iface->_var, net_dev); \ + \ + batadv_hardif_put(hard_iface); \ + return length; \ +} + +#define BATADV_ATTR_HIF_SHOW_UINT(_name, _var) \ +ssize_t batadv_show_##_name(struct kobject *kobj, \ + struct attribute *attr, char *buff) \ +{ \ + struct net_device *net_dev = batadv_kobj_to_netdev(kobj); \ + struct batadv_hard_iface *hard_iface; \ + ssize_t length; \ + \ + hard_iface = batadv_hardif_get_by_netdev(net_dev); \ + if (!hard_iface)\ + return 0; \ + \ + length = sprintf(buff, "%i\n", atomic_read(&hard_iface->_var)); \ + \ + batadv_hardif_put(hard_iface); \ + return length; \ +} + +/* Use this, if you are going to set [name] in hard_iface to an + * unsigned integer value + */ +#define BATADV_ATTR_HIF_UINT(_name, _var, _mode, _min, _max, _post_func)\ + static BATADV_ATTR_HIF_STORE_UINT(_name, _var, _min,\ + _max, _post_func) \ + static BATADV_ATTR_HIF_SHOW_UINT(_name, _var) \ + static BATADV_ATTR(_name, _mode, batadv_show_##_name, \ + batadv_store_##_name) + static int batadv_store_bool_attr(char *buff, size_t count, struct net_device *net_dev, const char *attr_name, atomic_t *attr, -- 2.7.2
[PATCH 07/15] batman-adv: add throughput override attribute to hard_ifaces
From: Antonio Quartulli This attribute is exported to user space to disable the link throughput auto-detection by setting a fixed value. The throughput override value is used when batman-adv is computing the link throughput towards a neighbour. If the value is set to 0 then batman-adv will try to detect the throughput by itself. Signed-off-by: Antonio Quartulli Signed-off-by: Marek Lindner --- .../ABI/testing/sysfs-class-net-batman-adv | 9 +++ net/batman-adv/bat_v.c | 6 ++ net/batman-adv/gateway_common.c| 4 +- net/batman-adv/gateway_common.h| 2 + net/batman-adv/sysfs.c | 74 ++ net/batman-adv/types.h | 2 + 6 files changed, 95 insertions(+), 2 deletions(-) diff --git a/Documentation/ABI/testing/sysfs-class-net-batman-adv b/Documentation/ABI/testing/sysfs-class-net-batman-adv index aea78db983bc..518f6a1dbc0c 100644 --- a/Documentation/ABI/testing/sysfs-class-net-batman-adv +++ b/Documentation/ABI/testing/sysfs-class-net-batman-adv @@ -1,4 +1,13 @@ +What: /sys/class/net//batman-adv/throughput_override +Date: Feb 2014 +Contact: Antonio Quartulli +description: + Defines the throughput value to be used by B.A.T.M.A.N. V + when estimating the link throughput using this interface. + If the value is set to 0 then batman-adv will try to + estimate the throughput by itself. + What: /sys/class/net//batman-adv/elp_interval Date: Feb 2014 Contact:Linus Lüssing diff --git a/net/batman-adv/bat_v.c b/net/batman-adv/bat_v.c index b90a4dfe8ba6..d9cb5c4922c1 100644 --- a/net/batman-adv/bat_v.c +++ b/net/batman-adv/bat_v.c @@ -18,6 +18,7 @@ #include "bat_algo.h" #include "main.h" +#include #include #include @@ -37,6 +38,11 @@ static int batadv_v_iface_enable(struct batadv_hard_iface *hard_iface) if (ret < 0) batadv_v_elp_iface_disable(hard_iface); + /* enable link throughput auto-detection by setting the throughput +* override to zero +*/ + atomic_set(&hard_iface->bat_v.throughput_override, 0); + return ret; } diff --git a/net/batman-adv/gateway_common.c b/net/batman-adv/gateway_common.c index 5ee04f7140af..4423047889e1 100644 --- a/net/batman-adv/gateway_common.c +++ b/net/batman-adv/gateway_common.c @@ -40,8 +40,8 @@ * * Return: false on parse error and true otherwise. */ -static bool batadv_parse_throughput(struct net_device *net_dev, char *buff, - const char *description, u32 *throughput) +bool batadv_parse_throughput(struct net_device *net_dev, char *buff, +const char *description, u32 *throughput) { enum batadv_bandwidth_units bw_unit_type = BATADV_BW_UNIT_KBIT; u64 lthroughput; diff --git a/net/batman-adv/gateway_common.h b/net/batman-adv/gateway_common.h index b58346350024..8a5e1ddf1175 100644 --- a/net/batman-adv/gateway_common.h +++ b/net/batman-adv/gateway_common.h @@ -49,5 +49,7 @@ ssize_t batadv_gw_bandwidth_set(struct net_device *net_dev, char *buff, void batadv_gw_tvlv_container_update(struct batadv_priv *bat_priv); void batadv_gw_init(struct batadv_priv *bat_priv); void batadv_gw_free(struct batadv_priv *bat_priv); +bool batadv_parse_throughput(struct net_device *net_dev, char *buff, +const char *description, u32 *throughput); #endif /* _NET_BATMAN_ADV_GATEWAY_COMMON_H_ */ diff --git a/net/batman-adv/sysfs.c b/net/batman-adv/sysfs.c index e86014332e1c..e7cf51333a36 100644 --- a/net/batman-adv/sysfs.c +++ b/net/batman-adv/sysfs.c @@ -917,12 +917,85 @@ static ssize_t batadv_show_iface_status(struct kobject *kobj, return length; } +#ifdef CONFIG_BATMAN_ADV_BATMAN_V + +/** + * batadv_store_throughput_override - parse and store throughput override + * entered by the user + * @kobj: kobject representing the private mesh sysfs directory + * @attr: the batman-adv attribute the user is interacting with + * @buff: the buffer containing the user data + * @count: number of bytes in the buffer + * + * Return: 'count' on success or a negative error code in case of failure + */ +static ssize_t batadv_store_throughput_override(struct kobject *kobj, + struct attribute *attr, + char *buff, size_t count) +{ + struct net_device *net_dev = batadv_kobj_to_netdev(kobj); + struct batadv_hard_iface *hard_iface; + u32 tp_override; + u32 old_tp_override; + bool ret; + + hard_iface = batadv_hardif_get_by_netdev(net_dev); + if (!hard_iface) + return -EINVAL; + + if (buff[count - 1] == '\n') + buff[count - 1] = '\0&
pull request [net-next]: batman-adv 20160229
Hello David, this is our (hopefully) latest batch of patches intended for net-next. With this patchset we finally introduce B.A.T.M.A.N. V: the latest version of our routing protocol. Technical documentation describing the protocol in more detail can be found in our wiki[1][2][3][4]. For what concerns this pull request, you can find the high level description right below. Please pull or let me know of any problem! Thank you very much, Antonio [1] https://www.open-mesh.org/projects/batman-adv/wiki/BATMAN_V [2] https://www.open-mesh.org/projects/batman-adv/wiki/OGMv2 [3] https://www.open-mesh.org/projects/batman-adv/wiki/ELP [4] https://www.open-mesh.org/projects/batman-adv/wiki/BATMAN_V_Tests The following changes since commit f12d33f4d83c6837d176e1aef337914089c77957: 3c59x: Ensure to apply the expires time (2016-02-28 23:39:26 -0500) are available in the git repository at: git://git.open-mesh.org/linux-merge.git tags/batman-adv-for-davem for you to fetch changes up to 8b823170550e5dcc80512143088c9f9e24598f9a: MAINTAINERS: Add patchwork URL for BATMAN ADVANCED (2016-02-29 16:25:09 +0800) With this patchset we finally introduce our new routing protocol: B.A.T.M.A.N. V. Its implementation started quite some years ago, but due to the big changes being introduced it took a while to be discussed, designed, worked, re-worked, tested and debugged (well, we're never done with the latest). The entire operation has basically been a team work involving all the core contributors together with other people interested in the project. The new protocol is divided into two main subcomponents, called respectively ELP and OGMv2. The former is in charge of dealing with the neighbour discovery and link quality estimation, while the latter implements the algorithm that spreads the metrics around the network and computes optimal paths. The biggest change introduced with B.A.T.M.A.N. V is the new metric: the protocol won't rely on packet loss anymore, but it will use the estimated throughput extracted directly from the wifi driver (when available) by querying cfg80211. Batman-adv will also send some unicast probing packets when an interface is not used for payload traffic to make sure that such values are current. The new protocol can be compiled-in or not like other features we have and when selected will pull in CFG80211 as dependency for the reason described above. Thanks to the big work brought up in the past by Marek Lindner, batman-adv can easily deal several protocol implementations, therefore compiling in this new version does not exclude the older. This means that the user is offered the option to choose the protocol when creating the mesh interface (default is the old one to keep backward compatibility). Along with the protocol there are some sysfs knobs that are introduced to fine tune some of its behaviours, but users are recommended to keep the default values unless they know what they are doing. The last patch is about advertising our own patchwork platform (thanks to Sven Eckelmann for having set that up!) in the MAINTAINERS file. -------- Antonio Quartulli (8): batman-adv: OGMv2 - add basic infrastructure batman-adv: OGMv2 - implement originators logic batman-adv: add throughput override attribute to hard_ifaces batman-adv: keep track of when unicast packets are sent batman-adv: ELP - compute the metric based on the estimated throughput batman-adv: ELP - send unicast ELP packets for throughput sampling batman-adv: B.A.T.M.A.N. V - implement neighbor comparison API calls batman-adv: B.A.T.M.A.N. V - implement bat_orig_print API Linus Luessing (5): batman-adv: Add hard_iface specific sysfs wrapper macros for UINT batman-adv: ELP - adding basic infrastructure batman-adv: ELP - creating neighbor structures batman-adv: ELP - adding sysfs parameter for elp interval batman-adv: B.A.T.M.A.N. V - implement bat_neigh_print API Simon Wunderlich (1): batman-adv: Start new development cycle Sven Eckelmann (1): MAINTAINERS: Add patchwork URL for BATMAN ADVANCED .../ABI/testing/sysfs-class-net-batman-adv | 17 +- MAINTAINERS| 1 + net/batman-adv/Kconfig | 14 + net/batman-adv/Makefile| 3 + net/batman-adv/bat_algo.h | 28 +- net/batman-adv/bat_iv_ogm.c| 2 +- net/batman-adv/bat_v.c | 347 + net/batman-adv/bat_v_elp.c | 515 + net/batman-adv/bat_v_elp.h | 33 + net/batman-adv/bat_v_ogm.c | 833 + net/batman-adv/bat_v_ogm.h | 36 + net/batman-adv/d
[PATCH 19/20] batman-adv: Rename batadv_tt_global_entry *_free_ref function to *_put
From: Sven Eckelmann The batman-adv source code is the only place in the kernel which uses the *_free_ref naming scheme for the *_put functions. Changing it to *_put makes it more consistent and makes it easier to understand the connection to the *_get functions. Signed-off-by: Sven Eckelmann Signed-off-by: Marek Lindner Signed-off-by: Antonio Quartulli --- net/batman-adv/translation-table.c | 32 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c index de3e731542e3..7f65a8f17f52 100644 --- a/net/batman-adv/translation-table.c +++ b/net/batman-adv/translation-table.c @@ -247,12 +247,12 @@ static void batadv_tt_global_entry_release(struct kref *ref) } /** - * batadv_tt_global_entry_free_ref - decrement the tt_global_entry refcounter - * and possibly release it + * batadv_tt_global_entry_put - decrement the tt_global_entry refcounter and + * possibly release it * @tt_global_entry: tt_global_entry to be free'd */ static void -batadv_tt_global_entry_free_ref(struct batadv_tt_global_entry *tt_global_entry) +batadv_tt_global_entry_put(struct batadv_tt_global_entry *tt_global_entry) { kref_put(&tt_global_entry->common.refcount, batadv_tt_global_entry_release); @@ -278,7 +278,7 @@ int batadv_tt_global_hash_count(struct batadv_priv *bat_priv, return 0; count = atomic_read(&tt_global_entry->orig_list_count); - batadv_tt_global_entry_free_ref(tt_global_entry); + batadv_tt_global_entry_put(tt_global_entry); return count; } @@ -561,7 +561,7 @@ static void batadv_tt_global_free(struct batadv_priv *bat_priv, batadv_hash_remove(bat_priv->tt.global_hash, batadv_compare_tt, batadv_choose_tt, &tt_global->common); - batadv_tt_global_entry_free_ref(tt_global); + batadv_tt_global_entry_put(tt_global); } /** @@ -756,7 +756,7 @@ out: if (tt_local) batadv_tt_local_entry_put(tt_local); if (tt_global) - batadv_tt_global_entry_free_ref(tt_global); + batadv_tt_global_entry_put(tt_global); return ret; } @@ -1467,7 +1467,7 @@ static bool batadv_tt_global_add(struct batadv_priv *bat_priv, if (unlikely(hash_added != 0)) { /* remove the reference for the hash */ - batadv_tt_global_entry_free_ref(tt_global_entry); + batadv_tt_global_entry_put(tt_global_entry); goto out_remove; } } else { @@ -1553,7 +1553,7 @@ out_remove: out: if (tt_global_entry) - batadv_tt_global_entry_free_ref(tt_global_entry); + batadv_tt_global_entry_put(tt_global_entry); if (tt_local_entry) batadv_tt_local_entry_put(tt_local_entry); return ret; @@ -1909,7 +1909,7 @@ static void batadv_tt_global_del(struct batadv_priv *bat_priv, out: if (tt_global_entry) - batadv_tt_global_entry_free_ref(tt_global_entry); + batadv_tt_global_entry_put(tt_global_entry); if (local_entry) batadv_tt_local_entry_put(local_entry); } @@ -1965,7 +1965,7 @@ void batadv_tt_global_del_orig(struct batadv_priv *bat_priv, tt_global->common.addr, BATADV_PRINT_VID(vid), message); hlist_del_rcu(&tt_common_entry->hash_entry); - batadv_tt_global_entry_free_ref(tt_global); + batadv_tt_global_entry_put(tt_global); } } spin_unlock_bh(list_lock); @@ -2028,7 +2028,7 @@ static void batadv_tt_global_purge(struct batadv_priv *bat_priv) hlist_del_rcu(&tt_common->hash_entry); - batadv_tt_global_entry_free_ref(tt_global); + batadv_tt_global_entry_put(tt_global); } spin_unlock_bh(list_lock); } @@ -2060,7 +2060,7 @@ static void batadv_tt_global_table_free(struct batadv_priv *bat_priv) tt_global = container_of(tt_common_entry, struct batadv_tt_global_entry, common); - batadv_tt_global_entry_free_ref(tt_global); + batadv_tt_global_entry_put(tt_global); } spin_unlock_bh(list_lock); } @@ -2141,7 +2141,7 @@ struct batadv_orig_node *batadv_transtable_search(struct batadv_priv *bat_priv, out: if (tt_global_entry) - batadv_tt_global_entry_free_ref(tt_global_entry); + batadv_tt_global_entry_pu
[PATCH 15/20] batman-adv: Rename batadv_nc_node *_free_ref function to *_put
From: Sven Eckelmann The batman-adv source code is the only place in the kernel which uses the *_free_ref naming scheme for the *_put functions. Changing it to *_put makes it more consistent and makes it easier to understand the connection to the *_get functions. Signed-off-by: Sven Eckelmann Signed-off-by: Marek Lindner Signed-off-by: Antonio Quartulli --- net/batman-adv/network-coding.c | 10 +- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/net/batman-adv/network-coding.c b/net/batman-adv/network-coding.c index 9180ff114a26..6105cfb0574c 100644 --- a/net/batman-adv/network-coding.c +++ b/net/batman-adv/network-coding.c @@ -223,11 +223,11 @@ static void batadv_nc_node_release(struct kref *ref) } /** - * batadv_nc_node_free_ref - decrement the nc_node refcounter and possibly + * batadv_nc_node_put - decrement the nc_node refcounter and possibly * release it * @nc_node: nc_node to be free'd */ -static void batadv_nc_node_free_ref(struct batadv_nc_node *nc_node) +static void batadv_nc_node_put(struct batadv_nc_node *nc_node) { kref_put(&nc_node->refcount, batadv_nc_node_release); } @@ -356,7 +356,7 @@ batadv_nc_purge_orig_nc_nodes(struct batadv_priv *bat_priv, "Removing nc_node %pM -> %pM\n", nc_node->addr, nc_node->orig_node->orig); list_del_rcu(&nc_node->list); - batadv_nc_node_free_ref(nc_node); + batadv_nc_node_put(nc_node); } spin_unlock_bh(lock); } @@ -942,9 +942,9 @@ void batadv_nc_update_nc_node(struct batadv_priv *bat_priv, out: if (in_nc_node) - batadv_nc_node_free_ref(in_nc_node); + batadv_nc_node_put(in_nc_node); if (out_nc_node) - batadv_nc_node_free_ref(out_nc_node); + batadv_nc_node_put(out_nc_node); } /** -- 2.7.1
[PATCH 10/20] batman-adv: Rename batadv_dat_entry *_free_ref function to *_put
From: Sven Eckelmann The batman-adv source code is the only place in the kernel which uses the *_free_ref naming scheme for the *_put functions. Changing it to *_put makes it more consistent and makes it easier to understand the connection to the *_get functions. Signed-off-by: Sven Eckelmann Signed-off-by: Marek Lindner Signed-off-by: Antonio Quartulli --- net/batman-adv/distributed-arp-table.c | 16 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/net/batman-adv/distributed-arp-table.c b/net/batman-adv/distributed-arp-table.c index 919f3445fff3..4c9b69d465a6 100644 --- a/net/batman-adv/distributed-arp-table.c +++ b/net/batman-adv/distributed-arp-table.c @@ -77,11 +77,11 @@ static void batadv_dat_entry_release(struct kref *ref) } /** - * batadv_dat_entry_free_ref - decrement the dat_entry refcounter and possibly + * batadv_dat_entry_put - decrement the dat_entry refcounter and possibly * release it * @dat_entry: dat_entry to be free'd */ -static void batadv_dat_entry_free_ref(struct batadv_dat_entry *dat_entry) +static void batadv_dat_entry_put(struct batadv_dat_entry *dat_entry) { kref_put(&dat_entry->refcount, batadv_dat_entry_release); } @@ -135,7 +135,7 @@ static void __batadv_dat_purge(struct batadv_priv *bat_priv, continue; hlist_del_rcu(&dat_entry->hash_entry); - batadv_dat_entry_free_ref(dat_entry); + batadv_dat_entry_put(dat_entry); } spin_unlock_bh(list_lock); } @@ -349,7 +349,7 @@ static void batadv_dat_entry_add(struct batadv_priv *bat_priv, __be32 ip, if (unlikely(hash_added != 0)) { /* remove the reference for the hash */ - batadv_dat_entry_free_ref(dat_entry); + batadv_dat_entry_put(dat_entry); goto out; } @@ -358,7 +358,7 @@ static void batadv_dat_entry_add(struct batadv_priv *bat_priv, __be32 ip, out: if (dat_entry) - batadv_dat_entry_free_ref(dat_entry); + batadv_dat_entry_put(dat_entry); } #ifdef CONFIG_BATMAN_ADV_DEBUG @@ -1029,7 +1029,7 @@ bool batadv_dat_snoop_outgoing_arp_request(struct batadv_priv *bat_priv, } out: if (dat_entry) - batadv_dat_entry_free_ref(dat_entry); + batadv_dat_entry_put(dat_entry); return ret; } @@ -1109,7 +1109,7 @@ bool batadv_dat_snoop_incoming_arp_request(struct batadv_priv *bat_priv, } out: if (dat_entry) - batadv_dat_entry_free_ref(dat_entry); + batadv_dat_entry_put(dat_entry); if (ret) kfree_skb(skb); return ret; @@ -1262,6 +1262,6 @@ bool batadv_dat_drop_broadcast_packet(struct batadv_priv *bat_priv, out: if (dat_entry) - batadv_dat_entry_free_ref(dat_entry); + batadv_dat_entry_put(dat_entry); return ret; } -- 2.7.1
[PATCH 13/20] batman-adv: Rename batadv_tvlv_container *_free_ref function to *_put
From: Sven Eckelmann The batman-adv source code is the only place in the kernel which uses the *_free_ref naming scheme for the *_put functions. Changing it to *_put makes it more consistent and makes it easier to understand the connection to the *_get functions. Signed-off-by: Sven Eckelmann Signed-off-by: Marek Lindner Signed-off-by: Antonio Quartulli --- net/batman-adv/main.c | 8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/net/batman-adv/main.c b/net/batman-adv/main.c index 95aaff371966..bf8a01b8f026 100644 --- a/net/batman-adv/main.c +++ b/net/batman-adv/main.c @@ -694,11 +694,11 @@ static void batadv_tvlv_container_release(struct kref *ref) } /** - * batadv_tvlv_container_free_ref - decrement the tvlv container refcounter and + * batadv_tvlv_container_put - decrement the tvlv container refcounter and * possibly release it * @tvlv: the tvlv container to free */ -static void batadv_tvlv_container_free_ref(struct batadv_tvlv_container *tvlv) +static void batadv_tvlv_container_put(struct batadv_tvlv_container *tvlv) { kref_put(&tvlv->refcount, batadv_tvlv_container_release); } @@ -784,8 +784,8 @@ static void batadv_tvlv_container_remove(struct batadv_priv *bat_priv, hlist_del(&tvlv->list); /* first call to decrement the counter, second call to free */ - batadv_tvlv_container_free_ref(tvlv); - batadv_tvlv_container_free_ref(tvlv); + batadv_tvlv_container_put(tvlv); + batadv_tvlv_container_put(tvlv); } /** -- 2.7.1
[PATCH 14/20] batman-adv: Rename batadv_softif_vlan *_free_ref function to *_put
From: Sven Eckelmann The batman-adv source code is the only place in the kernel which uses the *_free_ref naming scheme for the *_put functions. Changing it to *_put makes it more consistent and makes it easier to understand the connection to the *_get functions. Signed-off-by: Sven Eckelmann Signed-off-by: Marek Lindner Signed-off-by: Antonio Quartulli --- net/batman-adv/main.c | 2 +- net/batman-adv/soft-interface.c| 14 +++--- net/batman-adv/soft-interface.h| 2 +- net/batman-adv/sysfs.c | 4 ++-- net/batman-adv/translation-table.c | 20 ++-- 5 files changed, 21 insertions(+), 21 deletions(-) diff --git a/net/batman-adv/main.c b/net/batman-adv/main.c index bf8a01b8f026..e3d7051747b0 100644 --- a/net/batman-adv/main.c +++ b/net/batman-adv/main.c @@ -1261,7 +1261,7 @@ bool batadv_vlan_ap_isola_get(struct batadv_priv *bat_priv, unsigned short vid) vlan = batadv_softif_vlan_get(bat_priv, vid); if (vlan) { ap_isolation_enabled = atomic_read(&vlan->ap_isolation); - batadv_softif_vlan_free_ref(vlan); + batadv_softif_vlan_put(vlan); } return ap_isolation_enabled; diff --git a/net/batman-adv/soft-interface.c b/net/batman-adv/soft-interface.c index ca8fa4e28d4f..0710379491bf 100644 --- a/net/batman-adv/soft-interface.c +++ b/net/batman-adv/soft-interface.c @@ -497,11 +497,11 @@ static void batadv_softif_vlan_release(struct kref *ref) } /** - * batadv_softif_vlan_free_ref - decrease the vlan object refcounter and + * batadv_softif_vlan_put - decrease the vlan object refcounter and * possibly release it * @vlan: the vlan object to release */ -void batadv_softif_vlan_free_ref(struct batadv_softif_vlan *vlan) +void batadv_softif_vlan_put(struct batadv_softif_vlan *vlan) { if (!vlan) return; @@ -552,7 +552,7 @@ int batadv_softif_create_vlan(struct batadv_priv *bat_priv, unsigned short vid) vlan = batadv_softif_vlan_get(bat_priv, vid); if (vlan) { - batadv_softif_vlan_free_ref(vlan); + batadv_softif_vlan_put(vlan); return -EEXIST; } @@ -601,7 +601,7 @@ static void batadv_softif_destroy_vlan(struct batadv_priv *bat_priv, vlan->vid, "vlan interface destroyed", false); batadv_sysfs_del_vlan(bat_priv, vlan); - batadv_softif_vlan_free_ref(vlan); + batadv_softif_vlan_put(vlan); } /** @@ -646,7 +646,7 @@ static int batadv_interface_add_vid(struct net_device *dev, __be16 proto, if (!vlan->kobj) { ret = batadv_sysfs_add_vlan(bat_priv->soft_iface, vlan); if (ret) { - batadv_softif_vlan_free_ref(vlan); + batadv_softif_vlan_put(vlan); return ret; } } @@ -693,7 +693,7 @@ static int batadv_interface_kill_vid(struct net_device *dev, __be16 proto, batadv_softif_destroy_vlan(bat_priv, vlan); /* finally free the vlan object */ - batadv_softif_vlan_free_ref(vlan); + batadv_softif_vlan_put(vlan); return 0; } @@ -749,7 +749,7 @@ static void batadv_softif_destroy_finish(struct work_struct *work) vlan = batadv_softif_vlan_get(bat_priv, BATADV_NO_FLAGS); if (vlan) { batadv_softif_destroy_vlan(bat_priv, vlan); - batadv_softif_vlan_free_ref(vlan); + batadv_softif_vlan_put(vlan); } batadv_sysfs_del_meshif(soft_iface); diff --git a/net/batman-adv/soft-interface.h b/net/batman-adv/soft-interface.h index d17cfbacf809..9ae265703d23 100644 --- a/net/batman-adv/soft-interface.h +++ b/net/batman-adv/soft-interface.h @@ -34,7 +34,7 @@ void batadv_softif_destroy_sysfs(struct net_device *soft_iface); int batadv_softif_is_valid(const struct net_device *net_dev); extern struct rtnl_link_ops batadv_link_ops; int batadv_softif_create_vlan(struct batadv_priv *bat_priv, unsigned short vid); -void batadv_softif_vlan_free_ref(struct batadv_softif_vlan *softif_vlan); +void batadv_softif_vlan_put(struct batadv_softif_vlan *softif_vlan); struct batadv_softif_vlan *batadv_softif_vlan_get(struct batadv_priv *bat_priv, unsigned short vid); diff --git a/net/batman-adv/sysfs.c b/net/batman-adv/sysfs.c index 0db7591a000f..4d70d4413e40 100644 --- a/net/batman-adv/sysfs.c +++ b/net/batman-adv/sysfs.c @@ -216,7 +216,7 @@ ssize_t batadv_store_vlan_##_name(struct kobject *kobj, \ attr, &vlan->_name, \ bat_priv->soft_iface);\ \ - batadv_softif_vlan_free_ref(vlan); \