aggregation.c 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273
  1. /*
  2. * Copyright (C) 2007-2011 B.A.T.M.A.N. contributors:
  3. *
  4. * Marek Lindner, Simon Wunderlich
  5. *
  6. * This program is free software; you can redistribute it and/or
  7. * modify it under the terms of version 2 of the GNU General Public
  8. * License as published by the Free Software Foundation.
  9. *
  10. * This program is distributed in the hope that it will be useful, but
  11. * WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  13. * General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this program; if not, write to the Free Software
  17. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  18. * 02110-1301, USA
  19. *
  20. */
  21. #include "main.h"
  22. #include "aggregation.h"
  23. #include "send.h"
  24. #include "routing.h"
  25. /* calculate the size of the hna information for a given packet */
  26. static int hna_len(struct batman_packet *batman_packet)
  27. {
  28. return batman_packet->num_hna * ETH_ALEN;
  29. }
  30. /* return true if new_packet can be aggregated with forw_packet */
  31. static bool can_aggregate_with(struct batman_packet *new_batman_packet,
  32. int packet_len,
  33. unsigned long send_time,
  34. bool directlink,
  35. struct hard_iface *if_incoming,
  36. struct forw_packet *forw_packet)
  37. {
  38. struct batman_packet *batman_packet =
  39. (struct batman_packet *)forw_packet->skb->data;
  40. int aggregated_bytes = forw_packet->packet_len + packet_len;
  41. /**
  42. * we can aggregate the current packet to this aggregated packet
  43. * if:
  44. *
  45. * - the send time is within our MAX_AGGREGATION_MS time
  46. * - the resulting packet wont be bigger than
  47. * MAX_AGGREGATION_BYTES
  48. */
  49. if (time_before(send_time, forw_packet->send_time) &&
  50. time_after_eq(send_time + msecs_to_jiffies(MAX_AGGREGATION_MS),
  51. forw_packet->send_time) &&
  52. (aggregated_bytes <= MAX_AGGREGATION_BYTES)) {
  53. /**
  54. * check aggregation compatibility
  55. * -> direct link packets are broadcasted on
  56. * their interface only
  57. * -> aggregate packet if the current packet is
  58. * a "global" packet as well as the base
  59. * packet
  60. */
  61. /* packets without direct link flag and high TTL
  62. * are flooded through the net */
  63. if ((!directlink) &&
  64. (!(batman_packet->flags & DIRECTLINK)) &&
  65. (batman_packet->ttl != 1) &&
  66. /* own packets originating non-primary
  67. * interfaces leave only that interface */
  68. ((!forw_packet->own) ||
  69. (forw_packet->if_incoming->if_num == 0)))
  70. return true;
  71. /* if the incoming packet is sent via this one
  72. * interface only - we still can aggregate */
  73. if ((directlink) &&
  74. (new_batman_packet->ttl == 1) &&
  75. (forw_packet->if_incoming == if_incoming) &&
  76. /* packets from direct neighbors or
  77. * own secondary interface packets
  78. * (= secondary interface packets in general) */
  79. (batman_packet->flags & DIRECTLINK ||
  80. (forw_packet->own &&
  81. forw_packet->if_incoming->if_num != 0)))
  82. return true;
  83. }
  84. return false;
  85. }
  86. #define atomic_dec_not_zero(v) atomic_add_unless((v), -1, 0)
  87. /* create a new aggregated packet and add this packet to it */
  88. static void new_aggregated_packet(unsigned char *packet_buff, int packet_len,
  89. unsigned long send_time, bool direct_link,
  90. struct hard_iface *if_incoming,
  91. int own_packet)
  92. {
  93. struct bat_priv *bat_priv = netdev_priv(if_incoming->soft_iface);
  94. struct forw_packet *forw_packet_aggr;
  95. unsigned char *skb_buff;
  96. /* own packet should always be scheduled */
  97. if (!own_packet) {
  98. if (!atomic_dec_not_zero(&bat_priv->batman_queue_left)) {
  99. bat_dbg(DBG_BATMAN, bat_priv,
  100. "batman packet queue full\n");
  101. return;
  102. }
  103. }
  104. forw_packet_aggr = kmalloc(sizeof(struct forw_packet), GFP_ATOMIC);
  105. if (!forw_packet_aggr) {
  106. if (!own_packet)
  107. atomic_inc(&bat_priv->batman_queue_left);
  108. return;
  109. }
  110. if ((atomic_read(&bat_priv->aggregated_ogms)) &&
  111. (packet_len < MAX_AGGREGATION_BYTES))
  112. forw_packet_aggr->skb = dev_alloc_skb(MAX_AGGREGATION_BYTES +
  113. sizeof(struct ethhdr));
  114. else
  115. forw_packet_aggr->skb = dev_alloc_skb(packet_len +
  116. sizeof(struct ethhdr));
  117. if (!forw_packet_aggr->skb) {
  118. if (!own_packet)
  119. atomic_inc(&bat_priv->batman_queue_left);
  120. kfree(forw_packet_aggr);
  121. return;
  122. }
  123. skb_reserve(forw_packet_aggr->skb, sizeof(struct ethhdr));
  124. INIT_HLIST_NODE(&forw_packet_aggr->list);
  125. skb_buff = skb_put(forw_packet_aggr->skb, packet_len);
  126. forw_packet_aggr->packet_len = packet_len;
  127. memcpy(skb_buff, packet_buff, packet_len);
  128. forw_packet_aggr->own = own_packet;
  129. forw_packet_aggr->if_incoming = if_incoming;
  130. forw_packet_aggr->num_packets = 0;
  131. forw_packet_aggr->direct_link_flags = 0;
  132. forw_packet_aggr->send_time = send_time;
  133. /* save packet direct link flag status */
  134. if (direct_link)
  135. forw_packet_aggr->direct_link_flags |= 1;
  136. /* add new packet to packet list */
  137. spin_lock_bh(&bat_priv->forw_bat_list_lock);
  138. hlist_add_head(&forw_packet_aggr->list, &bat_priv->forw_bat_list);
  139. spin_unlock_bh(&bat_priv->forw_bat_list_lock);
  140. /* start timer for this packet */
  141. INIT_DELAYED_WORK(&forw_packet_aggr->delayed_work,
  142. send_outstanding_bat_packet);
  143. queue_delayed_work(bat_event_workqueue,
  144. &forw_packet_aggr->delayed_work,
  145. send_time - jiffies);
  146. }
  147. /* aggregate a new packet into the existing aggregation */
  148. static void aggregate(struct forw_packet *forw_packet_aggr,
  149. unsigned char *packet_buff,
  150. int packet_len,
  151. bool direct_link)
  152. {
  153. unsigned char *skb_buff;
  154. skb_buff = skb_put(forw_packet_aggr->skb, packet_len);
  155. memcpy(skb_buff, packet_buff, packet_len);
  156. forw_packet_aggr->packet_len += packet_len;
  157. forw_packet_aggr->num_packets++;
  158. /* save packet direct link flag status */
  159. if (direct_link)
  160. forw_packet_aggr->direct_link_flags |=
  161. (1 << forw_packet_aggr->num_packets);
  162. }
  163. void add_bat_packet_to_list(struct bat_priv *bat_priv,
  164. unsigned char *packet_buff, int packet_len,
  165. struct hard_iface *if_incoming, char own_packet,
  166. unsigned long send_time)
  167. {
  168. /**
  169. * _aggr -> pointer to the packet we want to aggregate with
  170. * _pos -> pointer to the position in the queue
  171. */
  172. struct forw_packet *forw_packet_aggr = NULL, *forw_packet_pos = NULL;
  173. struct hlist_node *tmp_node;
  174. struct batman_packet *batman_packet =
  175. (struct batman_packet *)packet_buff;
  176. bool direct_link = batman_packet->flags & DIRECTLINK ? 1 : 0;
  177. /* find position for the packet in the forward queue */
  178. spin_lock_bh(&bat_priv->forw_bat_list_lock);
  179. /* own packets are not to be aggregated */
  180. if ((atomic_read(&bat_priv->aggregated_ogms)) && (!own_packet)) {
  181. hlist_for_each_entry(forw_packet_pos, tmp_node,
  182. &bat_priv->forw_bat_list, list) {
  183. if (can_aggregate_with(batman_packet,
  184. packet_len,
  185. send_time,
  186. direct_link,
  187. if_incoming,
  188. forw_packet_pos)) {
  189. forw_packet_aggr = forw_packet_pos;
  190. break;
  191. }
  192. }
  193. }
  194. /* nothing to aggregate with - either aggregation disabled or no
  195. * suitable aggregation packet found */
  196. if (!forw_packet_aggr) {
  197. /* the following section can run without the lock */
  198. spin_unlock_bh(&bat_priv->forw_bat_list_lock);
  199. /**
  200. * if we could not aggregate this packet with one of the others
  201. * we hold it back for a while, so that it might be aggregated
  202. * later on
  203. */
  204. if ((!own_packet) &&
  205. (atomic_read(&bat_priv->aggregated_ogms)))
  206. send_time += msecs_to_jiffies(MAX_AGGREGATION_MS);
  207. new_aggregated_packet(packet_buff, packet_len,
  208. send_time, direct_link,
  209. if_incoming, own_packet);
  210. } else {
  211. aggregate(forw_packet_aggr,
  212. packet_buff, packet_len,
  213. direct_link);
  214. spin_unlock_bh(&bat_priv->forw_bat_list_lock);
  215. }
  216. }
  217. /* unpack the aggregated packets and process them one by one */
  218. void receive_aggr_bat_packet(struct ethhdr *ethhdr, unsigned char *packet_buff,
  219. int packet_len, struct hard_iface *if_incoming)
  220. {
  221. struct batman_packet *batman_packet;
  222. int buff_pos = 0;
  223. unsigned char *hna_buff;
  224. batman_packet = (struct batman_packet *)packet_buff;
  225. do {
  226. /* network to host order for our 32bit seqno, and the
  227. orig_interval. */
  228. batman_packet->seqno = ntohl(batman_packet->seqno);
  229. hna_buff = packet_buff + buff_pos + BAT_PACKET_LEN;
  230. receive_bat_packet(ethhdr, batman_packet,
  231. hna_buff, hna_len(batman_packet),
  232. if_incoming);
  233. buff_pos += BAT_PACKET_LEN + hna_len(batman_packet);
  234. batman_packet = (struct batman_packet *)
  235. (packet_buff + buff_pos);
  236. } while (aggregated_packet(buff_pos, packet_len,
  237. batman_packet->num_hna));
  238. }