aboutsummaryrefslogtreecommitdiffstats
path: root/net/batman-adv/soft-interface.c
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2011-05-02 18:04:46 -0400
committerDavid S. Miller <davem@davemloft.net>2011-05-02 18:04:46 -0400
commitdcfd9cdc1222f14d6180514e533289493a0716fb (patch)
tree8a60386e7e55c44fc08c02506380989a3c83a166 /net/batman-adv/soft-interface.c
parent5615787257742aab42ecf17c11e3244d9536a48d (diff)
parent32ae9b221e788413ce68feaae2ca39e406211a0a (diff)
Merge branch 'batman-adv/next' of git://git.open-mesh.org/ecsv/linux-merge
Diffstat (limited to 'net/batman-adv/soft-interface.c')
-rw-r--r--net/batman-adv/soft-interface.c64
1 files changed, 45 insertions, 19 deletions
diff --git a/net/batman-adv/soft-interface.c b/net/batman-adv/soft-interface.c
index eeabbb89172c..9e5fcd1596cf 100644
--- a/net/batman-adv/soft-interface.c
+++ b/net/batman-adv/soft-interface.c
@@ -211,13 +211,24 @@ int softif_neigh_seq_print_text(struct seq_file *seq, void *offset)
211 struct net_device *net_dev = (struct net_device *)seq->private; 211 struct net_device *net_dev = (struct net_device *)seq->private;
212 struct bat_priv *bat_priv = netdev_priv(net_dev); 212 struct bat_priv *bat_priv = netdev_priv(net_dev);
213 struct softif_neigh *softif_neigh; 213 struct softif_neigh *softif_neigh;
214 struct hard_iface *primary_if;
214 struct hlist_node *node; 215 struct hlist_node *node;
215 struct softif_neigh *curr_softif_neigh; 216 struct softif_neigh *curr_softif_neigh;
217 int ret = 0;
216 218
217 if (!bat_priv->primary_if) { 219 primary_if = primary_if_get_selected(bat_priv);
218 return seq_printf(seq, "BATMAN mesh %s disabled - " 220 if (!primary_if) {
219 "please specify interfaces to enable it\n", 221 ret = seq_printf(seq, "BATMAN mesh %s disabled - "
220 net_dev->name); 222 "please specify interfaces to enable it\n",
223 net_dev->name);
224 goto out;
225 }
226
227 if (primary_if->if_status != IF_ACTIVE) {
228 ret = seq_printf(seq, "BATMAN mesh %s "
229 "disabled - primary interface not active\n",
230 net_dev->name);
231 goto out;
221 } 232 }
222 233
223 seq_printf(seq, "Softif neighbor list (%s)\n", net_dev->name); 234 seq_printf(seq, "Softif neighbor list (%s)\n", net_dev->name);
@@ -234,7 +245,10 @@ int softif_neigh_seq_print_text(struct seq_file *seq, void *offset)
234 if (curr_softif_neigh) 245 if (curr_softif_neigh)
235 softif_neigh_free_ref(curr_softif_neigh); 246 softif_neigh_free_ref(curr_softif_neigh);
236 247
237 return 0; 248out:
249 if (primary_if)
250 hardif_free_ref(primary_if);
251 return ret;
238} 252}
239 253
240static void softif_batman_recv(struct sk_buff *skb, struct net_device *dev, 254static void softif_batman_recv(struct sk_buff *skb, struct net_device *dev,
@@ -243,7 +257,8 @@ static void softif_batman_recv(struct sk_buff *skb, struct net_device *dev,
243 struct bat_priv *bat_priv = netdev_priv(dev); 257 struct bat_priv *bat_priv = netdev_priv(dev);
244 struct ethhdr *ethhdr = (struct ethhdr *)skb->data; 258 struct ethhdr *ethhdr = (struct ethhdr *)skb->data;
245 struct batman_packet *batman_packet; 259 struct batman_packet *batman_packet;
246 struct softif_neigh *softif_neigh; 260 struct softif_neigh *softif_neigh = NULL;
261 struct hard_iface *primary_if = NULL;
247 struct softif_neigh *curr_softif_neigh = NULL; 262 struct softif_neigh *curr_softif_neigh = NULL;
248 263
249 if (ntohs(ethhdr->h_proto) == ETH_P_8021Q) 264 if (ntohs(ethhdr->h_proto) == ETH_P_8021Q)
@@ -253,28 +268,34 @@ static void softif_batman_recv(struct sk_buff *skb, struct net_device *dev,
253 batman_packet = (struct batman_packet *)(skb->data + ETH_HLEN); 268 batman_packet = (struct batman_packet *)(skb->data + ETH_HLEN);
254 269
255 if (batman_packet->version != COMPAT_VERSION) 270 if (batman_packet->version != COMPAT_VERSION)
256 goto err; 271 goto out;
257 272
258 if (batman_packet->packet_type != BAT_PACKET) 273 if (batman_packet->packet_type != BAT_PACKET)
259 goto err; 274 goto out;
260 275
261 if (!(batman_packet->flags & PRIMARIES_FIRST_HOP)) 276 if (!(batman_packet->flags & PRIMARIES_FIRST_HOP))
262 goto err; 277 goto out;
263 278
264 if (is_my_mac(batman_packet->orig)) 279 if (is_my_mac(batman_packet->orig))
265 goto err; 280 goto out;
266 281
267 softif_neigh = softif_neigh_get(bat_priv, batman_packet->orig, vid); 282 softif_neigh = softif_neigh_get(bat_priv, batman_packet->orig, vid);
268
269 if (!softif_neigh) 283 if (!softif_neigh)
270 goto err; 284 goto out;
271 285
272 curr_softif_neigh = softif_neigh_get_selected(bat_priv); 286 curr_softif_neigh = softif_neigh_get_selected(bat_priv);
287 if (!curr_softif_neigh)
288 goto out;
289
273 if (curr_softif_neigh == softif_neigh) 290 if (curr_softif_neigh == softif_neigh)
274 goto out; 291 goto out;
275 292
293 primary_if = primary_if_get_selected(bat_priv);
294 if (!primary_if)
295 goto out;
296
276 /* we got a neighbor but its mac is 'bigger' than ours */ 297 /* we got a neighbor but its mac is 'bigger' than ours */
277 if (memcmp(bat_priv->primary_if->net_dev->dev_addr, 298 if (memcmp(primary_if->net_dev->dev_addr,
278 softif_neigh->addr, ETH_ALEN) < 0) 299 softif_neigh->addr, ETH_ALEN) < 0)
279 goto out; 300 goto out;
280 301
@@ -296,7 +317,7 @@ static void softif_batman_recv(struct sk_buff *skb, struct net_device *dev,
296 /* close own batX device and use softif_neigh as exit node */ 317 /* close own batX device and use softif_neigh as exit node */
297 if ((!curr_softif_neigh) && 318 if ((!curr_softif_neigh) &&
298 (memcmp(softif_neigh->addr, 319 (memcmp(softif_neigh->addr,
299 bat_priv->primary_if->net_dev->dev_addr, ETH_ALEN) < 0)) { 320 primary_if->net_dev->dev_addr, ETH_ALEN) < 0)) {
300 bat_dbg(DBG_ROUTES, bat_priv, 321 bat_dbg(DBG_ROUTES, bat_priv,
301 "Setting mesh exit point to %pM (vid: %d).\n", 322 "Setting mesh exit point to %pM (vid: %d).\n",
302 softif_neigh->addr, softif_neigh->vid); 323 softif_neigh->addr, softif_neigh->vid);
@@ -306,12 +327,13 @@ static void softif_batman_recv(struct sk_buff *skb, struct net_device *dev,
306 } 327 }
307 328
308out: 329out:
309 softif_neigh_free_ref(softif_neigh);
310err:
311 kfree_skb(skb); 330 kfree_skb(skb);
331 if (softif_neigh)
332 softif_neigh_free_ref(softif_neigh);
312 if (curr_softif_neigh) 333 if (curr_softif_neigh)
313 softif_neigh_free_ref(curr_softif_neigh); 334 softif_neigh_free_ref(curr_softif_neigh);
314 335 if (primary_if)
336 hardif_free_ref(primary_if);
315 return; 337 return;
316} 338}
317 339
@@ -367,6 +389,7 @@ int interface_tx(struct sk_buff *skb, struct net_device *soft_iface)
367{ 389{
368 struct ethhdr *ethhdr = (struct ethhdr *)skb->data; 390 struct ethhdr *ethhdr = (struct ethhdr *)skb->data;
369 struct bat_priv *bat_priv = netdev_priv(soft_iface); 391 struct bat_priv *bat_priv = netdev_priv(soft_iface);
392 struct hard_iface *primary_if = NULL;
370 struct bcast_packet *bcast_packet; 393 struct bcast_packet *bcast_packet;
371 struct vlan_ethhdr *vhdr; 394 struct vlan_ethhdr *vhdr;
372 struct softif_neigh *curr_softif_neigh = NULL; 395 struct softif_neigh *curr_softif_neigh = NULL;
@@ -416,7 +439,8 @@ int interface_tx(struct sk_buff *skb, struct net_device *soft_iface)
416 439
417 /* ethernet packet should be broadcasted */ 440 /* ethernet packet should be broadcasted */
418 if (do_bcast) { 441 if (do_bcast) {
419 if (!bat_priv->primary_if) 442 primary_if = primary_if_get_selected(bat_priv);
443 if (!primary_if)
420 goto dropped; 444 goto dropped;
421 445
422 if (my_skb_head_push(skb, sizeof(struct bcast_packet)) < 0) 446 if (my_skb_head_push(skb, sizeof(struct bcast_packet)) < 0)
@@ -432,7 +456,7 @@ int interface_tx(struct sk_buff *skb, struct net_device *soft_iface)
432 /* hw address of first interface is the orig mac because only 456 /* hw address of first interface is the orig mac because only
433 * this mac is known throughout the mesh */ 457 * this mac is known throughout the mesh */
434 memcpy(bcast_packet->orig, 458 memcpy(bcast_packet->orig,
435 bat_priv->primary_if->net_dev->dev_addr, ETH_ALEN); 459 primary_if->net_dev->dev_addr, ETH_ALEN);
436 460
437 /* set broadcast sequence number */ 461 /* set broadcast sequence number */
438 bcast_packet->seqno = 462 bcast_packet->seqno =
@@ -462,6 +486,8 @@ dropped_freed:
462end: 486end:
463 if (curr_softif_neigh) 487 if (curr_softif_neigh)
464 softif_neigh_free_ref(curr_softif_neigh); 488 softif_neigh_free_ref(curr_softif_neigh);
489 if (primary_if)
490 hardif_free_ref(primary_if);
465 return NETDEV_TX_OK; 491 return NETDEV_TX_OK;
466} 492}
467 493