diff options
author | Marek Lindner <lindner_marek@yahoo.de> | 2012-03-01 02:35:17 -0500 |
---|---|---|
committer | Antonio Quartulli <ordex@autistici.org> | 2012-05-11 04:08:10 -0400 |
commit | ffa995e036bef734ea40cbbccda574d1df3a8a58 (patch) | |
tree | 396d7c202f1b0d82dce905e7d70c32708886f404 /net/batman-adv/hard-interface.c | |
parent | 75cd33f86396c446f84c4bb620be70c36a2a54f6 (diff) |
batman-adv: introduce packet type handler array for incoming packets
The packet handler array replaces the growing switch statement, thus
dealing with incoming packets in a more efficient way. It also adds
to possibility to register packet handlers on the fly.
Signed-off-by: Marek Lindner <lindner_marek@yahoo.de>
Acked-by: Simon Wunderlich <siwu@hrz.tu-chemnitz.de>
Signed-off-by: Antonio Quartulli <ordex@autistici.org>
Diffstat (limited to 'net/batman-adv/hard-interface.c')
-rw-r--r-- | net/batman-adv/hard-interface.c | 113 |
1 files changed, 0 insertions, 113 deletions
diff --git a/net/batman-adv/hard-interface.c b/net/batman-adv/hard-interface.c index 47c79d724ba3..95f869c7ca04 100644 --- a/net/batman-adv/hard-interface.c +++ b/net/batman-adv/hard-interface.c | |||
@@ -32,12 +32,6 @@ | |||
32 | 32 | ||
33 | #include <linux/if_arp.h> | 33 | #include <linux/if_arp.h> |
34 | 34 | ||
35 | |||
36 | static int batman_skb_recv(struct sk_buff *skb, | ||
37 | struct net_device *dev, | ||
38 | struct packet_type *ptype, | ||
39 | struct net_device *orig_dev); | ||
40 | |||
41 | void hardif_free_rcu(struct rcu_head *rcu) | 35 | void hardif_free_rcu(struct rcu_head *rcu) |
42 | { | 36 | { |
43 | struct hard_iface *hard_iface; | 37 | struct hard_iface *hard_iface; |
@@ -551,113 +545,6 @@ out: | |||
551 | return NOTIFY_DONE; | 545 | return NOTIFY_DONE; |
552 | } | 546 | } |
553 | 547 | ||
554 | /* incoming packets with the batman ethertype received on any active hard | ||
555 | * interface */ | ||
556 | static int batman_skb_recv(struct sk_buff *skb, struct net_device *dev, | ||
557 | struct packet_type *ptype, | ||
558 | struct net_device *orig_dev) | ||
559 | { | ||
560 | struct bat_priv *bat_priv; | ||
561 | struct batman_ogm_packet *batman_ogm_packet; | ||
562 | struct hard_iface *hard_iface; | ||
563 | int ret; | ||
564 | |||
565 | hard_iface = container_of(ptype, struct hard_iface, batman_adv_ptype); | ||
566 | skb = skb_share_check(skb, GFP_ATOMIC); | ||
567 | |||
568 | /* skb was released by skb_share_check() */ | ||
569 | if (!skb) | ||
570 | goto err_out; | ||
571 | |||
572 | /* packet should hold at least type and version */ | ||
573 | if (unlikely(!pskb_may_pull(skb, 2))) | ||
574 | goto err_free; | ||
575 | |||
576 | /* expect a valid ethernet header here. */ | ||
577 | if (unlikely(skb->mac_len != ETH_HLEN || !skb_mac_header(skb))) | ||
578 | goto err_free; | ||
579 | |||
580 | if (!hard_iface->soft_iface) | ||
581 | goto err_free; | ||
582 | |||
583 | bat_priv = netdev_priv(hard_iface->soft_iface); | ||
584 | |||
585 | if (atomic_read(&bat_priv->mesh_state) != MESH_ACTIVE) | ||
586 | goto err_free; | ||
587 | |||
588 | /* discard frames on not active interfaces */ | ||
589 | if (hard_iface->if_status != IF_ACTIVE) | ||
590 | goto err_free; | ||
591 | |||
592 | batman_ogm_packet = (struct batman_ogm_packet *)skb->data; | ||
593 | |||
594 | if (batman_ogm_packet->header.version != COMPAT_VERSION) { | ||
595 | bat_dbg(DBG_BATMAN, bat_priv, | ||
596 | "Drop packet: incompatible batman version (%i)\n", | ||
597 | batman_ogm_packet->header.version); | ||
598 | goto err_free; | ||
599 | } | ||
600 | |||
601 | /* all receive handlers return whether they received or reused | ||
602 | * the supplied skb. if not, we have to free the skb. */ | ||
603 | |||
604 | switch (batman_ogm_packet->header.packet_type) { | ||
605 | /* batman originator packet */ | ||
606 | case BAT_IV_OGM: | ||
607 | ret = recv_bat_ogm_packet(skb, hard_iface); | ||
608 | break; | ||
609 | |||
610 | /* batman icmp packet */ | ||
611 | case BAT_ICMP: | ||
612 | ret = recv_icmp_packet(skb, hard_iface); | ||
613 | break; | ||
614 | |||
615 | /* unicast packet */ | ||
616 | case BAT_UNICAST: | ||
617 | ret = recv_unicast_packet(skb, hard_iface); | ||
618 | break; | ||
619 | |||
620 | /* fragmented unicast packet */ | ||
621 | case BAT_UNICAST_FRAG: | ||
622 | ret = recv_ucast_frag_packet(skb, hard_iface); | ||
623 | break; | ||
624 | |||
625 | /* broadcast packet */ | ||
626 | case BAT_BCAST: | ||
627 | ret = recv_bcast_packet(skb, hard_iface); | ||
628 | break; | ||
629 | |||
630 | /* vis packet */ | ||
631 | case BAT_VIS: | ||
632 | ret = recv_vis_packet(skb, hard_iface); | ||
633 | break; | ||
634 | /* Translation table query (request or response) */ | ||
635 | case BAT_TT_QUERY: | ||
636 | ret = recv_tt_query(skb, hard_iface); | ||
637 | break; | ||
638 | /* Roaming advertisement */ | ||
639 | case BAT_ROAM_ADV: | ||
640 | ret = recv_roam_adv(skb, hard_iface); | ||
641 | break; | ||
642 | default: | ||
643 | ret = NET_RX_DROP; | ||
644 | } | ||
645 | |||
646 | if (ret == NET_RX_DROP) | ||
647 | kfree_skb(skb); | ||
648 | |||
649 | /* return NET_RX_SUCCESS in any case as we | ||
650 | * most probably dropped the packet for | ||
651 | * routing-logical reasons. */ | ||
652 | |||
653 | return NET_RX_SUCCESS; | ||
654 | |||
655 | err_free: | ||
656 | kfree_skb(skb); | ||
657 | err_out: | ||
658 | return NET_RX_DROP; | ||
659 | } | ||
660 | |||
661 | /* This function returns true if the interface represented by ifindex is a | 548 | /* This function returns true if the interface represented by ifindex is a |
662 | * 802.11 wireless device */ | 549 | * 802.11 wireless device */ |
663 | bool is_wifi_iface(int ifindex) | 550 | bool is_wifi_iface(int ifindex) |