aboutsummaryrefslogtreecommitdiffstats
path: root/net/batman-adv
diff options
context:
space:
mode:
authorSimon Wunderlich <simon.wunderlich@s2003.tu-chemnitz.de>2012-01-22 14:00:24 -0500
committerAntonio Quartulli <ordex@autistici.org>2012-04-11 08:28:59 -0400
commitfe2da6ff27c73c1d102ec2189f94e8bc729d1a9b (patch)
tree143055e9de797c3b645d453a5d0c62d5c3d8af19 /net/batman-adv
parent20ff9d593f8ff20c2ef24498f77a8bc30b3a059a (diff)
batman-adv: add broadcast duplicate check
When multiple backbone gateways relay the same broadcast from the backbone into the mesh, other nodes in the mesh may receive this broadcast multiple times. To avoid this, the crc checksums of received broadcasts are recorded and new broadcast packets with the same content may be dropped if received by another gateway. Signed-off-by: Simon Wunderlich <siwu@hrz.tu-chemnitz.de> Signed-off-by: Antonio Quartulli <ordex@autistici.org>
Diffstat (limited to 'net/batman-adv')
-rw-r--r--net/batman-adv/bridge_loop_avoidance.c75
-rw-r--r--net/batman-adv/bridge_loop_avoidance.h2
-rw-r--r--net/batman-adv/main.h3
-rw-r--r--net/batman-adv/routing.c4
-rw-r--r--net/batman-adv/types.h7
5 files changed, 91 insertions, 0 deletions
diff --git a/net/batman-adv/bridge_loop_avoidance.c b/net/batman-adv/bridge_loop_avoidance.c
index 6186f6e92e33..4f6b44a5b128 100644
--- a/net/batman-adv/bridge_loop_avoidance.c
+++ b/net/batman-adv/bridge_loop_avoidance.c
@@ -1041,8 +1041,16 @@ out:
1041/* initialize all bla structures */ 1041/* initialize all bla structures */
1042int bla_init(struct bat_priv *bat_priv) 1042int bla_init(struct bat_priv *bat_priv)
1043{ 1043{
1044 int i;
1045
1044 bat_dbg(DBG_BLA, bat_priv, "bla hash registering\n"); 1046 bat_dbg(DBG_BLA, bat_priv, "bla hash registering\n");
1045 1047
1048 /* initialize the duplicate list */
1049 for (i = 0; i < DUPLIST_SIZE; i++)
1050 bat_priv->bcast_duplist[i].entrytime =
1051 jiffies - msecs_to_jiffies(DUPLIST_TIMEOUT);
1052 bat_priv->bcast_duplist_curr = 0;
1053
1046 if (bat_priv->claim_hash) 1054 if (bat_priv->claim_hash)
1047 return 1; 1055 return 1;
1048 1056
@@ -1060,6 +1068,73 @@ int bla_init(struct bat_priv *bat_priv)
1060 1068
1061/** 1069/**
1062 * @bat_priv: the bat priv with all the soft interface information 1070 * @bat_priv: the bat priv with all the soft interface information
1071 * @bcast_packet: originator mac address
1072 * @hdr_size: maximum length of the frame
1073 *
1074 * check if it is on our broadcast list. Another gateway might
1075 * have sent the same packet because it is connected to the same backbone,
1076 * so we have to remove this duplicate.
1077 *
1078 * This is performed by checking the CRC, which will tell us
1079 * with a good chance that it is the same packet. If it is furthermore
1080 * sent by another host, drop it. We allow equal packets from
1081 * the same host however as this might be intended.
1082 *
1083 **/
1084
1085int bla_check_bcast_duplist(struct bat_priv *bat_priv,
1086 struct bcast_packet *bcast_packet,
1087 int hdr_size)
1088{
1089 int i, length, curr;
1090 uint8_t *content;
1091 uint16_t crc;
1092 struct bcast_duplist_entry *entry;
1093
1094 length = hdr_size - sizeof(*bcast_packet);
1095 content = (uint8_t *)bcast_packet;
1096 content += sizeof(*bcast_packet);
1097
1098 /* calculate the crc ... */
1099 crc = crc16(0, content, length);
1100
1101 for (i = 0 ; i < DUPLIST_SIZE; i++) {
1102 curr = (bat_priv->bcast_duplist_curr + i) % DUPLIST_SIZE;
1103 entry = &bat_priv->bcast_duplist[curr];
1104
1105 /* we can stop searching if the entry is too old ;
1106 * later entries will be even older
1107 */
1108 if (has_timed_out(entry->entrytime, DUPLIST_TIMEOUT))
1109 break;
1110
1111 if (entry->crc != crc)
1112 continue;
1113
1114 if (compare_eth(entry->orig, bcast_packet->orig))
1115 continue;
1116
1117 /* this entry seems to match: same crc, not too old,
1118 * and from another gw. therefore return 1 to forbid it.
1119 */
1120 return 1;
1121 }
1122 /* not found, add a new entry (overwrite the oldest entry) */
1123 curr = (bat_priv->bcast_duplist_curr + DUPLIST_SIZE - 1) % DUPLIST_SIZE;
1124 entry = &bat_priv->bcast_duplist[curr];
1125 entry->crc = crc;
1126 entry->entrytime = jiffies;
1127 memcpy(entry->orig, bcast_packet->orig, ETH_ALEN);
1128 bat_priv->bcast_duplist_curr = curr;
1129
1130 /* allow it, its the first occurence. */
1131 return 0;
1132}
1133
1134
1135
1136/**
1137 * @bat_priv: the bat priv with all the soft interface information
1063 * @orig: originator mac address 1138 * @orig: originator mac address
1064 * 1139 *
1065 * check if the originator is a gateway for any VLAN ID. 1140 * check if the originator is a gateway for any VLAN ID.
diff --git a/net/batman-adv/bridge_loop_avoidance.h b/net/batman-adv/bridge_loop_avoidance.h
index b74940f09baf..9468c245121c 100644
--- a/net/batman-adv/bridge_loop_avoidance.h
+++ b/net/batman-adv/bridge_loop_avoidance.h
@@ -28,6 +28,8 @@ int bla_is_backbone_gw(struct sk_buff *skb,
28 struct orig_node *orig_node, int hdr_size); 28 struct orig_node *orig_node, int hdr_size);
29int bla_claim_table_seq_print_text(struct seq_file *seq, void *offset); 29int bla_claim_table_seq_print_text(struct seq_file *seq, void *offset);
30int bla_is_backbone_gw_orig(struct bat_priv *bat_priv, uint8_t *orig); 30int bla_is_backbone_gw_orig(struct bat_priv *bat_priv, uint8_t *orig);
31int bla_check_bcast_duplist(struct bat_priv *bat_priv,
32 struct bcast_packet *bcast_packet, int hdr_size);
31void bla_update_orig_address(struct bat_priv *bat_priv, 33void bla_update_orig_address(struct bat_priv *bat_priv,
32 struct hard_iface *primary_if, 34 struct hard_iface *primary_if,
33 struct hard_iface *oldif); 35 struct hard_iface *oldif);
diff --git a/net/batman-adv/main.h b/net/batman-adv/main.h
index 82723b5dce61..d9832acf558d 100644
--- a/net/batman-adv/main.h
+++ b/net/batman-adv/main.h
@@ -83,6 +83,9 @@
83#define BLA_PERIOD_LENGTH 10000 /* 10 seconds */ 83#define BLA_PERIOD_LENGTH 10000 /* 10 seconds */
84#define BLA_BACKBONE_TIMEOUT (BLA_PERIOD_LENGTH * 3) 84#define BLA_BACKBONE_TIMEOUT (BLA_PERIOD_LENGTH * 3)
85#define BLA_CLAIM_TIMEOUT (BLA_PERIOD_LENGTH * 10) 85#define BLA_CLAIM_TIMEOUT (BLA_PERIOD_LENGTH * 10)
86
87#define DUPLIST_SIZE 16
88#define DUPLIST_TIMEOUT 500 /* 500 ms */
86/* don't reset again within 30 seconds */ 89/* don't reset again within 30 seconds */
87#define RESET_PROTECTION_MS 30000 90#define RESET_PROTECTION_MS 30000
88#define EXPECTED_SEQNO_RANGE 65536 91#define EXPECTED_SEQNO_RANGE 65536
diff --git a/net/batman-adv/routing.c b/net/batman-adv/routing.c
index 1d1fd04c9c3a..78eddc9067e6 100644
--- a/net/batman-adv/routing.c
+++ b/net/batman-adv/routing.c
@@ -1076,6 +1076,10 @@ int recv_bcast_packet(struct sk_buff *skb, struct hard_iface *recv_if)
1076 1076
1077 spin_unlock_bh(&orig_node->bcast_seqno_lock); 1077 spin_unlock_bh(&orig_node->bcast_seqno_lock);
1078 1078
1079 /* check whether this has been sent by another originator before */
1080 if (bla_check_bcast_duplist(bat_priv, bcast_packet, hdr_size))
1081 goto out;
1082
1079 /* rebroadcast packet */ 1083 /* rebroadcast packet */
1080 add_bcast_packet_to_list(bat_priv, skb, 1); 1084 add_bcast_packet_to_list(bat_priv, skb, 1);
1081 1085
diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h
index 35cd831508a9..ad97e87a2e22 100644
--- a/net/batman-adv/types.h
+++ b/net/batman-adv/types.h
@@ -140,6 +140,11 @@ struct neigh_node {
140 spinlock_t tq_lock; /* protects: tq_recv, tq_index */ 140 spinlock_t tq_lock; /* protects: tq_recv, tq_index */
141}; 141};
142 142
143struct bcast_duplist_entry {
144 uint8_t orig[ETH_ALEN];
145 uint16_t crc;
146 unsigned long entrytime;
147};
143 148
144struct bat_priv { 149struct bat_priv {
145 atomic_t mesh_state; 150 atomic_t mesh_state;
@@ -186,6 +191,8 @@ struct bat_priv {
186 struct list_head tt_req_list; /* list of pending tt_requests */ 191 struct list_head tt_req_list; /* list of pending tt_requests */
187 struct list_head tt_roam_list; 192 struct list_head tt_roam_list;
188 struct hashtable_t *vis_hash; 193 struct hashtable_t *vis_hash;
194 struct bcast_duplist_entry bcast_duplist[DUPLIST_SIZE];
195 int bcast_duplist_curr;
189 spinlock_t forw_bat_list_lock; /* protects forw_bat_list */ 196 spinlock_t forw_bat_list_lock; /* protects forw_bat_list */
190 spinlock_t forw_bcast_list_lock; /* protects */ 197 spinlock_t forw_bcast_list_lock; /* protects */
191 spinlock_t tt_changes_list_lock; /* protects tt_changes */ 198 spinlock_t tt_changes_list_lock; /* protects tt_changes */