]> git.proxmox.com Git - mirror_ubuntu-hirsute-kernel.git/blame - net/batman-adv/bitarray.c
netfilter: x_tables: fix compat match/target pad out-of-bound write
[mirror_ubuntu-hirsute-kernel.git] / net / batman-adv / bitarray.c
CommitLineData
7db7d9f3 1// SPDX-License-Identifier: GPL-2.0
68e039f9 2/* Copyright (C) 2006-2020 B.A.T.M.A.N. contributors:
c6c8fea2
SE
3 *
4 * Simon Wunderlich, Marek Lindner
c6c8fea2
SE
5 */
6
c6c8fea2 7#include "bitarray.h"
1e2c2a4f 8#include "main.h"
c6c8fea2 9
1e2c2a4f 10#include <linux/bitmap.h>
c6c8fea2 11
ba412080
SE
12#include "log.h"
13
c6c8fea2 14/* shift the packet array by n places. */
6b5e971a 15static void batadv_bitmap_shift_left(unsigned long *seq_bits, s32 n)
c6c8fea2 16{
42d0b044 17 if (n <= 0 || n >= BATADV_TQ_LOCAL_WINDOW_SIZE)
c6c8fea2
SE
18 return;
19
42d0b044 20 bitmap_shift_left(seq_bits, seq_bits, n, BATADV_TQ_LOCAL_WINDOW_SIZE);
c6c8fea2
SE
21}
22
7afcbbef 23/**
7e9a8c2c 24 * batadv_bit_get_packet() - receive and process one packet within the sequence
7afcbbef
SE
25 * number window
26 * @priv: the bat priv with all the soft interface information
27 * @seq_bits: pointer to the sequence number receive packet
28 * @seq_num_diff: difference between the current/received sequence number and
29 * the last sequence number
30 * @set_mark: whether this packet should be marked in seq_bits
c6c8fea2 31 *
4b426b10
SE
32 * Return: true if the window was moved (either new or very old),
33 * false if the window was not moved/shifted.
c6c8fea2 34 */
4b426b10
SE
35bool batadv_bit_get_packet(void *priv, unsigned long *seq_bits,
36 s32 seq_num_diff, int set_mark)
c6c8fea2 37{
56303d34 38 struct batadv_priv *bat_priv = priv;
c6c8fea2
SE
39
40 /* sequence number is slightly older. We already got a sequence number
9cfc7bd6
SE
41 * higher than this one, so we just mark it.
42 */
42d0b044 43 if (seq_num_diff <= 0 && seq_num_diff > -BATADV_TQ_LOCAL_WINDOW_SIZE) {
c6c8fea2 44 if (set_mark)
9b4a1159 45 batadv_set_bit(seq_bits, -seq_num_diff);
4b426b10 46 return false;
c6c8fea2
SE
47 }
48
49 /* sequence number is slightly newer, so we shift the window and
9cfc7bd6
SE
50 * set the mark if required
51 */
42d0b044 52 if (seq_num_diff > 0 && seq_num_diff < BATADV_TQ_LOCAL_WINDOW_SIZE) {
0f5f9322 53 batadv_bitmap_shift_left(seq_bits, seq_num_diff);
c6c8fea2
SE
54
55 if (set_mark)
9b4a1159 56 batadv_set_bit(seq_bits, 0);
4b426b10 57 return true;
c6c8fea2
SE
58 }
59
60 /* sequence number is much newer, probably missed a lot of packets */
42d0b044
SE
61 if (seq_num_diff >= BATADV_TQ_LOCAL_WINDOW_SIZE &&
62 seq_num_diff < BATADV_EXPECTED_SEQNO_RANGE) {
39c75a51 63 batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
1eda58bf
SE
64 "We missed a lot of packets (%i) !\n",
65 seq_num_diff - 1);
42d0b044 66 bitmap_zero(seq_bits, BATADV_TQ_LOCAL_WINDOW_SIZE);
c6c8fea2 67 if (set_mark)
9b4a1159 68 batadv_set_bit(seq_bits, 0);
4b426b10 69 return true;
c6c8fea2
SE
70 }
71
72 /* received a much older packet. The other host either restarted
73 * or the old packet got delayed somewhere in the network. The
74 * packet should be dropped without calling this function if the
9cfc7bd6 75 * seqno window is protected.
8e7c15d6
SE
76 *
77 * seq_num_diff <= -BATADV_TQ_LOCAL_WINDOW_SIZE
78 * or
79 * seq_num_diff >= BATADV_EXPECTED_SEQNO_RANGE
9cfc7bd6 80 */
8e7c15d6
SE
81 batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
82 "Other host probably restarted!\n");
c6c8fea2 83
8e7c15d6
SE
84 bitmap_zero(seq_bits, BATADV_TQ_LOCAL_WINDOW_SIZE);
85 if (set_mark)
86 batadv_set_bit(seq_bits, 0);
c6c8fea2 87
4b426b10 88 return true;
c6c8fea2 89}