aboutsummaryrefslogtreecommitdiffstats
path: root/net/batman-adv/send.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/batman-adv/send.c')
-rw-r--r--net/batman-adv/send.c74
1 files changed, 1 insertions, 73 deletions
diff --git a/net/batman-adv/send.c b/net/batman-adv/send.c
index f5ff36492b2f..79f8973810c0 100644
--- a/net/batman-adv/send.c
+++ b/net/batman-adv/send.c
@@ -77,62 +77,9 @@ send_skb_err:
77 return NET_XMIT_DROP; 77 return NET_XMIT_DROP;
78} 78}
79 79
80static void realloc_packet_buffer(struct hard_iface *hard_iface,
81 int new_len)
82{
83 unsigned char *new_buff;
84
85 new_buff = kmalloc(new_len, GFP_ATOMIC);
86
87 /* keep old buffer if kmalloc should fail */
88 if (new_buff) {
89 memcpy(new_buff, hard_iface->packet_buff,
90 BATMAN_OGM_HLEN);
91
92 kfree(hard_iface->packet_buff);
93 hard_iface->packet_buff = new_buff;
94 hard_iface->packet_len = new_len;
95 }
96}
97
98/* when calling this function (hard_iface == primary_if) has to be true */
99static int prepare_packet_buffer(struct bat_priv *bat_priv,
100 struct hard_iface *hard_iface)
101{
102 int new_len;
103
104 new_len = BATMAN_OGM_HLEN +
105 tt_len((uint8_t)atomic_read(&bat_priv->tt_local_changes));
106
107 /* if we have too many changes for one packet don't send any
108 * and wait for the tt table request which will be fragmented */
109 if (new_len > hard_iface->soft_iface->mtu)
110 new_len = BATMAN_OGM_HLEN;
111
112 realloc_packet_buffer(hard_iface, new_len);
113
114 bat_priv->tt_crc = tt_local_crc(bat_priv);
115
116 /* reset the sending counter */
117 atomic_set(&bat_priv->tt_ogm_append_cnt, TT_OGM_APPEND_MAX);
118
119 return tt_changes_fill_buffer(bat_priv,
120 hard_iface->packet_buff + BATMAN_OGM_HLEN,
121 hard_iface->packet_len - BATMAN_OGM_HLEN);
122}
123
124static int reset_packet_buffer(struct bat_priv *bat_priv,
125 struct hard_iface *hard_iface)
126{
127 realloc_packet_buffer(hard_iface, BATMAN_OGM_HLEN);
128 return 0;
129}
130
131void schedule_bat_ogm(struct hard_iface *hard_iface) 80void schedule_bat_ogm(struct hard_iface *hard_iface)
132{ 81{
133 struct bat_priv *bat_priv = netdev_priv(hard_iface->soft_iface); 82 struct bat_priv *bat_priv = netdev_priv(hard_iface->soft_iface);
134 struct hard_iface *primary_if;
135 int tt_num_changes = -1;
136 83
137 if ((hard_iface->if_status == IF_NOT_IN_USE) || 84 if ((hard_iface->if_status == IF_NOT_IN_USE) ||
138 (hard_iface->if_status == IF_TO_BE_REMOVED)) 85 (hard_iface->if_status == IF_TO_BE_REMOVED))
@@ -148,26 +95,7 @@ void schedule_bat_ogm(struct hard_iface *hard_iface)
148 if (hard_iface->if_status == IF_TO_BE_ACTIVATED) 95 if (hard_iface->if_status == IF_TO_BE_ACTIVATED)
149 hard_iface->if_status = IF_ACTIVE; 96 hard_iface->if_status = IF_ACTIVE;
150 97
151 primary_if = primary_if_get_selected(bat_priv); 98 bat_priv->bat_algo_ops->bat_ogm_schedule(hard_iface);
152
153 if (hard_iface == primary_if) {
154 /* if at least one change happened */
155 if (atomic_read(&bat_priv->tt_local_changes) > 0) {
156 tt_commit_changes(bat_priv);
157 tt_num_changes = prepare_packet_buffer(bat_priv,
158 hard_iface);
159 }
160
161 /* if the changes have been sent often enough */
162 if (!atomic_dec_not_zero(&bat_priv->tt_ogm_append_cnt))
163 tt_num_changes = reset_packet_buffer(bat_priv,
164 hard_iface);
165 }
166
167 if (primary_if)
168 hardif_free_ref(primary_if);
169
170 bat_priv->bat_algo_ops->bat_ogm_schedule(hard_iface, tt_num_changes);
171} 99}
172 100
173static void forw_packet_free(struct forw_packet *forw_packet) 101static void forw_packet_free(struct forw_packet *forw_packet)