struct batman_packet *batman_packet)
 
 {
-       /* don't care if bonding is not enabled */
-       if (!atomic_read(&bat_priv->bonding_enabled)) {
-               orig_node->bond.candidates = 0;
-               return;
-       }
-
        if (batman_packet->flags & PRIMARIES_FIRST_HOP)
                memcpy(orig_neigh_node->primary_addr,
                       orig_node->orig, ETH_ALEN);
        struct neigh_node *tmp_neigh_node, *tmp_neigh_node2;
        struct neigh_node *first_candidate, *last_candidate;
 
-       /* don't care if bonding is not enabled */
-       if (!atomic_read(&bat_priv->bonding_enabled)) {
-               orig_node->bond.candidates = 0;
-               return;
-       }
-
        /* update the candidates for this originator */
        if (!orig_node->router) {
                orig_node->bond.candidates = 0;
 
 /* find a suitable router for this originator, and use
  * bonding if possible. */
-struct neigh_node *find_router(struct orig_node *orig_node)
+struct neigh_node *find_router(struct orig_node *orig_node,
+               struct batman_if *recv_if)
 {
        /* FIXME: each orig_node->batman_if will be attached to a softif */
        struct bat_priv *bat_priv = netdev_priv(soft_device);
        struct orig_node *primary_orig_node;
        struct orig_node *router_orig;
-       struct neigh_node *router;
+       struct neigh_node *router, *first_candidate, *best_router;
        static uint8_t zero_mac[ETH_ALEN] = {0, 0, 0, 0, 0, 0};
+       int bonding_enabled;
 
        if (!orig_node)
                return NULL;
        if (!orig_node->router)
                return NULL;
 
-       /* don't care if bonding is not enabled */
-       if (!atomic_read(&bat_priv->bonding_enabled))
-               return orig_node->router;
+       /* without bonding, the first node should
+        * always choose the default router. */
+
+       bonding_enabled = atomic_read(&bat_priv->bonding_enabled);
+       if (!bonding_enabled && (recv_if == NULL))
+                       return orig_node->router;
 
        router_orig = orig_node->router->orig_node;
 
        if (primary_orig_node->bond.candidates < 2)
                return orig_node->router;
 
-       router = primary_orig_node->bond.selected;
 
-       /* sanity check - this should never happen. */
-       if (!router)
-               return orig_node->router;
+       /* all nodes between should choose a candidate which
+        * is is not on the interface where the packet came
+        * in. */
+       first_candidate = primary_orig_node->bond.selected;
+       router = first_candidate;
+
+       if (bonding_enabled) {
+               /* in the bonding case, send the packets in a round
+                * robin fashion over the remaining interfaces. */
+               do {
+                       /* recv_if == NULL on the first node. */
+                       if (router->if_incoming != recv_if)
+                               break;
+
+                       router = router->next_bond_candidate;
+               } while (router != first_candidate);
+
+               primary_orig_node->bond.selected = router->next_bond_candidate;
 
-       /* select the next bonding partner ... */
-       primary_orig_node->bond.selected = router->next_bond_candidate;
+       } else {
+               /* if bonding is disabled, use the best of the
+                * remaining candidates which are not using
+                * this interface. */
+               best_router = first_candidate;
+
+               do {
+                       /* recv_if == NULL on the first node. */
+                       if ((router->if_incoming != recv_if) &&
+                               (router->tq_avg > best_router->tq_avg))
+                                       best_router = router;
+
+                       router = router->next_bond_candidate;
+               } while (router != first_candidate);
+
+               router = best_router;
+       }
 
        return router;
 }
 
-int recv_unicast_packet(struct sk_buff *skb)
+int recv_unicast_packet(struct sk_buff *skb, struct batman_if *recv_if)
 {
        struct unicast_packet *unicast_packet;
        struct orig_node *orig_node;
        orig_node = ((struct orig_node *)
                     hash_find(orig_hash, unicast_packet->dest));
 
-       router = find_router(orig_node);
+       router = find_router(orig_node, recv_if);
 
        if (!router) {
                spin_unlock_irqrestore(&orig_hash_lock, flags);
 
                                struct neigh_node *neigh_node,
                                unsigned char *hna_buff, int hna_buff_len);
 int recv_icmp_packet(struct sk_buff *skb);
-int recv_unicast_packet(struct sk_buff *skb);
+int recv_unicast_packet(struct sk_buff *skb, struct batman_if *recv_if);
 int recv_bcast_packet(struct sk_buff *skb);
 int recv_vis_packet(struct sk_buff *skb);
 int recv_bat_packet(struct sk_buff *skb,
                                struct batman_if *batman_if);
-struct neigh_node *find_router(struct orig_node *orig_node);
+struct neigh_node *find_router(struct orig_node *orig_node,
+               struct batman_if *recv_if);
 void update_bonding_candidates(struct bat_priv *bat_priv,
                               struct orig_node *orig_node);