]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - net/batman-adv/send.c
batman-adv: Initialize lockdep class keys for hashes
[karo-tx-linux.git] / net / batman-adv / send.c
index 570a8bce0364ea08ea45341b57b362a72beedc45..4425af9dad40e2b9698f48c576c27042c13a8dbb 100644 (file)
@@ -18,6 +18,7 @@
  */
 
 #include "main.h"
+#include "distributed-arp-table.h"
 #include "send.h"
 #include "routing.h"
 #include "translation-table.h"
@@ -27,6 +28,8 @@
 #include "gateway_common.h"
 #include "originator.h"
 
+#include <linux/if_ether.h>
+
 static void batadv_send_outstanding_bcast_packet(struct work_struct *work);
 
 /* send out an already prepared packet to the given address via the
@@ -59,11 +62,11 @@ int batadv_send_skb_packet(struct sk_buff *skb,
        ethhdr = (struct ethhdr *)skb_mac_header(skb);
        memcpy(ethhdr->h_source, hard_iface->net_dev->dev_addr, ETH_ALEN);
        memcpy(ethhdr->h_dest, dst_addr, ETH_ALEN);
-       ethhdr->h_proto = __constant_htons(BATADV_ETH_P_BATMAN);
+       ethhdr->h_proto = __constant_htons(ETH_P_BATMAN);
 
        skb_set_network_header(skb, ETH_HLEN);
        skb->priority = TC_PRIO_CONTROL;
-       skb->protocol = __constant_htons(BATADV_ETH_P_BATMAN);
+       skb->protocol = __constant_htons(ETH_P_BATMAN);
 
        skb->dev = hard_iface->net_dev;
 
@@ -77,6 +80,39 @@ send_skb_err:
        return NET_XMIT_DROP;
 }
 
+/**
+ * batadv_send_skb_to_orig - Lookup next-hop and transmit skb.
+ * @skb: Packet to be transmitted.
+ * @orig_node: Final destination of the packet.
+ * @recv_if: Interface used when receiving the packet (can be NULL).
+ *
+ * Looks up the best next-hop towards the passed originator and passes the
+ * skb on for preparation of MAC header. If the packet originated from this
+ * host, NULL can be passed as recv_if and no interface alternating is
+ * attempted.
+ *
+ * Returns TRUE on success; FALSE otherwise.
+ */
+bool batadv_send_skb_to_orig(struct sk_buff *skb,
+                            struct batadv_orig_node *orig_node,
+                            struct batadv_hard_iface *recv_if)
+{
+       struct batadv_priv *bat_priv = orig_node->bat_priv;
+       struct batadv_neigh_node *neigh_node;
+
+       /* batadv_find_router() increases neigh_nodes refcount if found. */
+       neigh_node = batadv_find_router(bat_priv, orig_node, recv_if);
+       if (!neigh_node)
+               return false;
+
+       /* route it */
+       batadv_send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr);
+
+       batadv_neigh_node_free_ref(neigh_node);
+
+       return true;
+}
+
 void batadv_schedule_bat_ogm(struct batadv_hard_iface *hard_iface)
 {
        struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface);
@@ -209,6 +245,9 @@ static void batadv_send_outstanding_bcast_packet(struct work_struct *work)
        if (atomic_read(&bat_priv->mesh_state) == BATADV_MESH_DEACTIVATING)
                goto out;
 
+       if (batadv_dat_drop_broadcast_packet(bat_priv, forw_packet))
+               goto out;
+
        /* rebroadcast packet */
        rcu_read_lock();
        list_for_each_entry_rcu(hard_iface, &batadv_hardif_list, list) {