diff options
Diffstat (limited to 'net/batman-adv/send.c')
-rw-r--r-- | net/batman-adv/send.c | 21 |
1 files changed, 15 insertions, 6 deletions
diff --git a/net/batman-adv/send.c b/net/batman-adv/send.c index 7a2f0823f1c2..4b8e11bc14fa 100644 --- a/net/batman-adv/send.c +++ b/net/batman-adv/send.c | |||
@@ -163,6 +163,7 @@ static void send_packet(struct forw_packet *forw_packet) | |||
163 | struct hard_iface *hard_iface; | 163 | struct hard_iface *hard_iface; |
164 | struct net_device *soft_iface; | 164 | struct net_device *soft_iface; |
165 | struct bat_priv *bat_priv; | 165 | struct bat_priv *bat_priv; |
166 | struct hard_iface *primary_if = NULL; | ||
166 | struct batman_packet *batman_packet = | 167 | struct batman_packet *batman_packet = |
167 | (struct batman_packet *)(forw_packet->skb->data); | 168 | (struct batman_packet *)(forw_packet->skb->data); |
168 | int directlink = (batman_packet->flags & DIRECTLINK ? 1 : 0); | 169 | int directlink = (batman_packet->flags & DIRECTLINK ? 1 : 0); |
@@ -170,19 +171,23 @@ static void send_packet(struct forw_packet *forw_packet) | |||
170 | if (!forw_packet->if_incoming) { | 171 | if (!forw_packet->if_incoming) { |
171 | pr_err("Error - can't forward packet: incoming iface not " | 172 | pr_err("Error - can't forward packet: incoming iface not " |
172 | "specified\n"); | 173 | "specified\n"); |
173 | return; | 174 | goto out; |
174 | } | 175 | } |
175 | 176 | ||
176 | soft_iface = forw_packet->if_incoming->soft_iface; | 177 | soft_iface = forw_packet->if_incoming->soft_iface; |
177 | bat_priv = netdev_priv(soft_iface); | 178 | bat_priv = netdev_priv(soft_iface); |
178 | 179 | ||
179 | if (forw_packet->if_incoming->if_status != IF_ACTIVE) | 180 | if (forw_packet->if_incoming->if_status != IF_ACTIVE) |
180 | return; | 181 | goto out; |
182 | |||
183 | primary_if = primary_if_get_selected(bat_priv); | ||
184 | if (!primary_if) | ||
185 | goto out; | ||
181 | 186 | ||
182 | /* multihomed peer assumed */ | 187 | /* multihomed peer assumed */ |
183 | /* non-primary OGMs are only broadcasted on their interface */ | 188 | /* non-primary OGMs are only broadcasted on their interface */ |
184 | if ((directlink && (batman_packet->ttl == 1)) || | 189 | if ((directlink && (batman_packet->ttl == 1)) || |
185 | (forw_packet->own && (forw_packet->if_incoming->if_num > 0))) { | 190 | (forw_packet->own && (forw_packet->if_incoming != primary_if))) { |
186 | 191 | ||
187 | /* FIXME: what about aggregated packets ? */ | 192 | /* FIXME: what about aggregated packets ? */ |
188 | bat_dbg(DBG_BATMAN, bat_priv, | 193 | bat_dbg(DBG_BATMAN, bat_priv, |
@@ -199,7 +204,7 @@ static void send_packet(struct forw_packet *forw_packet) | |||
199 | broadcast_addr); | 204 | broadcast_addr); |
200 | forw_packet->skb = NULL; | 205 | forw_packet->skb = NULL; |
201 | 206 | ||
202 | return; | 207 | goto out; |
203 | } | 208 | } |
204 | 209 | ||
205 | /* broadcast on every interface */ | 210 | /* broadcast on every interface */ |
@@ -211,6 +216,10 @@ static void send_packet(struct forw_packet *forw_packet) | |||
211 | send_packet_to_if(forw_packet, hard_iface); | 216 | send_packet_to_if(forw_packet, hard_iface); |
212 | } | 217 | } |
213 | rcu_read_unlock(); | 218 | rcu_read_unlock(); |
219 | |||
220 | out: | ||
221 | if (primary_if) | ||
222 | hardif_free_ref(primary_if); | ||
214 | } | 223 | } |
215 | 224 | ||
216 | static void realloc_packet_buffer(struct hard_iface *hard_iface, | 225 | static void realloc_packet_buffer(struct hard_iface *hard_iface, |
@@ -455,7 +464,7 @@ static void _add_bcast_packet_to_list(struct bat_priv *bat_priv, | |||
455 | * The skb is not consumed, so the caller should make sure that the | 464 | * The skb is not consumed, so the caller should make sure that the |
456 | * skb is freed. */ | 465 | * skb is freed. */ |
457 | int add_bcast_packet_to_list(struct bat_priv *bat_priv, | 466 | int add_bcast_packet_to_list(struct bat_priv *bat_priv, |
458 | const struct sk_buff *skb) | 467 | const struct sk_buff *skb, unsigned long delay) |
459 | { | 468 | { |
460 | struct hard_iface *primary_if = NULL; | 469 | struct hard_iface *primary_if = NULL; |
461 | struct forw_packet *forw_packet; | 470 | struct forw_packet *forw_packet; |
@@ -492,7 +501,7 @@ int add_bcast_packet_to_list(struct bat_priv *bat_priv, | |||
492 | /* how often did we send the bcast packet ? */ | 501 | /* how often did we send the bcast packet ? */ |
493 | forw_packet->num_packets = 0; | 502 | forw_packet->num_packets = 0; |
494 | 503 | ||
495 | _add_bcast_packet_to_list(bat_priv, forw_packet, 1); | 504 | _add_bcast_packet_to_list(bat_priv, forw_packet, delay); |
496 | return NETDEV_TX_OK; | 505 | return NETDEV_TX_OK; |
497 | 506 | ||
498 | packet_free: | 507 | packet_free: |