The following commit has been merged in the master branch: commit a20d4e9695e3cfc3fe933815cfd1a9304d24c0db Merge: 0314b0c48cdb72160e80cd6f64b2bbd46c47a7ef 688c216eef6b19b4a3650bdad0308a463bfd93ad Author: Sven Eckelmann sven@narfation.org Date: Wed Mar 28 18:29:37 2012 +0200
Merge branch 'next'
diff --combined compat.h index 46de8b0,4b86902..1cf5210 --- a/compat.h +++ b/compat.h @@@ -57,6 -57,13 +57,13 @@@
#endif /* < KERNEL_VERSION(2, 6, 34) */
+ #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 35) + + #define pr_warn pr_warning + + #endif /* < KERNEL_VERSION(2, 6, 35) */ + +
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 31)
@@@ -122,23 -129,22 +129,23 @@@ static inline int __param_set_copystrin #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 0, 0)
#define kfree_rcu(ptr, rcu_head) call_rcu(&ptr->rcu_head, free_rcu_##ptr) +#define vlan_insert_tag(skb, vid) __vlan_put_tag(skb, vid)
void free_rcu_gw_node(struct rcu_head *rcu); void free_rcu_neigh_node(struct rcu_head *rcu); -void free_rcu_softif_neigh(struct rcu_head *rcu); void free_rcu_tt_local_entry(struct rcu_head *rcu); +void free_rcu_backbone_gw(struct rcu_head *rcu);
#endif /* < KERNEL_VERSION(3, 0, 0) */
- #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 3, 0) + #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 4, 0)
static inline void eth_hw_addr_random(struct net_device *dev) { random_ether_addr(dev->dev_addr); }
- #endif /* < KERNEL_VERSION(3, 0, 0) */ + #endif /* < KERNEL_VERSION(3, 4, 0) */
#endif /* _NET_BATMAN_ADV_COMPAT_H_ */ diff --combined hard-interface.c index daa6adc,7db9636..2477d00 --- a/hard-interface.c +++ b/hard-interface.c @@@ -20,7 -20,6 +20,7 @@@ */
#include "main.h" +#include "distributed-arp-table.h" #include "hard-interface.h" #include "soft-interface.h" #include "send.h" @@@ -29,10 -28,15 +29,10 @@@ #include "bat_sysfs.h" #include "originator.h" #include "hash.h" +#include "bridge_loop_avoidance.h"
#include <linux/if_arp.h>
- -static int batman_skb_recv(struct sk_buff *skb, - struct net_device *dev, - struct packet_type *ptype, - struct net_device *orig_dev); - void hardif_free_rcu(struct rcu_head *rcu) { struct hard_iface *hard_iface; @@@ -103,8 -107,7 +103,8 @@@ out return hard_iface; }
-static void primary_if_update_addr(struct bat_priv *bat_priv) +static void primary_if_update_addr(struct bat_priv *bat_priv, + struct hard_iface *oldif) { struct vis_packet *vis_packet; struct hard_iface *primary_if; @@@ -113,15 -116,12 +113,15 @@@ if (!primary_if) goto out;
+ dat_init_own_dht_addr(bat_priv, primary_if); + vis_packet = (struct vis_packet *) bat_priv->my_vis_info->skb_packet->data; memcpy(vis_packet->vis_orig, primary_if->net_dev->dev_addr, ETH_ALEN); memcpy(vis_packet->sender_orig, primary_if->net_dev->dev_addr, ETH_ALEN);
+ bla_update_orig_address(bat_priv, primary_if, oldif); out: if (primary_if) hardif_free_ref(primary_if); @@@ -140,15 -140,14 +140,15 @@@ static void primary_if_select(struct ba curr_hard_iface = rcu_dereference_protected(bat_priv->primary_if, 1); rcu_assign_pointer(bat_priv->primary_if, new_hard_iface);
- if (curr_hard_iface) - hardif_free_ref(curr_hard_iface); - if (!new_hard_iface) - return; + goto out;
- bat_priv->bat_algo_ops->bat_ogm_init_primary(new_hard_iface); - primary_if_update_addr(bat_priv); + bat_priv->bat_algo_ops->bat_primary_iface_set(new_hard_iface); + primary_if_update_addr(bat_priv, curr_hard_iface); + +out: + if (curr_hard_iface) + hardif_free_ref(curr_hard_iface); }
static bool hardif_is_iface_up(const struct hard_iface *hard_iface) @@@ -176,9 -175,9 +176,9 @@@ static void check_known_mac_addr(const net_dev->dev_addr)) continue;
- pr_warning("The newly added mac address (%pM) already exists on: %s\n", + pr_warn("The newly added mac address (%pM) already exists on: %s\n", net_dev->dev_addr, hard_iface->net_dev->name); - pr_warning("It is strongly recommended to keep mac addresses unique to avoid problems!\n"); + pr_warn("It is strongly recommended to keep mac addresses unique to avoid problems!\n"); } rcu_read_unlock(); } @@@ -231,7 -230,7 +231,7 @@@ static void hardif_activate_interface(s
bat_priv = netdev_priv(hard_iface->soft_iface);
- bat_priv->bat_algo_ops->bat_ogm_update_mac(hard_iface); + bat_priv->bat_algo_ops->bat_iface_update_mac(hard_iface); hard_iface->if_status = IF_TO_BE_ACTIVATED;
/** @@@ -301,17 -300,22 +301,17 @@@ int hardif_enable_interface(struct hard if (!softif_is_valid(soft_iface)) { pr_err("Can't create batman mesh interface %s: already exists as regular interface\n", soft_iface->name); - dev_put(soft_iface); ret = -EINVAL; - goto err; + goto err_dev; }
hard_iface->soft_iface = soft_iface; bat_priv = netdev_priv(hard_iface->soft_iface);
- bat_priv->bat_algo_ops->bat_ogm_init(hard_iface); - - if (!hard_iface->packet_buff) { - bat_err(hard_iface->soft_iface, - "Can't add interface packet (%s): out of memory\n", - hard_iface->net_dev->name); + ret = bat_priv->bat_algo_ops->bat_iface_enable(hard_iface); + if (ret < 0) { ret = -ENOMEM; - goto err; + goto err_dev; }
hard_iface->if_num = bat_priv->num_ifaces; @@@ -324,6 -328,7 +324,6 @@@ hard_iface->batman_adv_ptype.dev = hard_iface->net_dev; dev_add_pack(&hard_iface->batman_adv_ptype);
- atomic_set(&hard_iface->seqno, 1); atomic_set(&hard_iface->frag_seqno, 1); bat_info(hard_iface->soft_iface, "Adding interface: %s\n", hard_iface->net_dev->name); @@@ -355,8 -360,6 +355,8 @@@ out: return 0;
+err_dev: + dev_put(soft_iface); err: hardif_free_ref(hard_iface); return ret; @@@ -391,7 -394,8 +391,7 @@@ void hardif_disable_interface(struct ha hardif_free_ref(new_if); }
- kfree(hard_iface->packet_buff); - hard_iface->packet_buff = NULL; + bat_priv->bat_algo_ops->bat_iface_disable(hard_iface); hard_iface->if_status = IF_NOT_IN_USE;
/* delete all references to this hard_iface */ @@@ -443,13 -447,6 +443,13 @@@ static struct hard_iface *hardif_add_in check_known_mac_addr(hard_iface->net_dev); list_add_tail_rcu(&hard_iface->list, &hardif_list);
+ /** + * This can't be called via a bat_priv callback because + * we have no bat_priv yet. + */ + atomic_set(&hard_iface->seqno, 1); + hard_iface->packet_buff = NULL; + return hard_iface;
free_if: @@@ -527,14 -524,14 +527,14 @@@ static int hard_if_event(struct notifie check_known_mac_addr(hard_iface->net_dev);
bat_priv = netdev_priv(hard_iface->soft_iface); - bat_priv->bat_algo_ops->bat_ogm_update_mac(hard_iface); + bat_priv->bat_algo_ops->bat_iface_update_mac(hard_iface);
primary_if = primary_if_get_selected(bat_priv); if (!primary_if) goto hardif_put;
if (hard_iface == primary_if) - primary_if_update_addr(bat_priv); + primary_if_update_addr(bat_priv, NULL); break; default: break; @@@ -548,6 -545,114 +548,6 @@@ out return NOTIFY_DONE; }
-/* incoming packets with the batman ethertype received on any active hard - * interface */ -static int batman_skb_recv(struct sk_buff *skb, struct net_device *dev, - struct packet_type *ptype, - struct net_device *orig_dev) -{ - struct bat_priv *bat_priv; - struct batman_ogm_packet *batman_ogm_packet; - struct hard_iface *hard_iface; - int ret; - - hard_iface = container_of(ptype, struct hard_iface, batman_adv_ptype); - skb = skb_share_check(skb, GFP_ATOMIC); - - /* skb was released by skb_share_check() */ - if (!skb) - goto err_out; - - /* packet should hold at least type and version */ - if (unlikely(!pskb_may_pull(skb, 2))) - goto err_free; - - /* expect a valid ethernet header here. */ - if (unlikely(skb->mac_len != sizeof(struct ethhdr) || - !skb_mac_header(skb))) - goto err_free; - - if (!hard_iface->soft_iface) - goto err_free; - - bat_priv = netdev_priv(hard_iface->soft_iface); - - if (atomic_read(&bat_priv->mesh_state) != MESH_ACTIVE) - goto err_free; - - /* discard frames on not active interfaces */ - if (hard_iface->if_status != IF_ACTIVE) - goto err_free; - - batman_ogm_packet = (struct batman_ogm_packet *)skb->data; - - if (batman_ogm_packet->header.version != COMPAT_VERSION) { - bat_dbg(DBG_BATMAN, bat_priv, - "Drop packet: incompatible batman version (%i)\n", - batman_ogm_packet->header.version); - goto err_free; - } - - /* all receive handlers return whether they received or reused - * the supplied skb. if not, we have to free the skb. */ - - switch (batman_ogm_packet->header.packet_type) { - /* batman originator packet */ - case BAT_OGM: - ret = recv_bat_ogm_packet(skb, hard_iface); - break; - - /* batman icmp packet */ - case BAT_ICMP: - ret = recv_icmp_packet(skb, hard_iface); - break; - - /* unicast packet */ - case BAT_UNICAST: - ret = recv_unicast_packet(skb, hard_iface); - break; - - /* fragmented unicast packet */ - case BAT_UNICAST_FRAG: - ret = recv_ucast_frag_packet(skb, hard_iface); - break; - - /* broadcast packet */ - case BAT_BCAST: - ret = recv_bcast_packet(skb, hard_iface); - break; - - /* vis packet */ - case BAT_VIS: - ret = recv_vis_packet(skb, hard_iface); - break; - /* Translation table query (request or response) */ - case BAT_TT_QUERY: - ret = recv_tt_query(skb, hard_iface); - break; - /* Roaming advertisement */ - case BAT_ROAM_ADV: - ret = recv_roam_adv(skb, hard_iface); - break; - default: - ret = NET_RX_DROP; - } - - if (ret == NET_RX_DROP) - kfree_skb(skb); - - /* return NET_RX_SUCCESS in any case as we - * most probably dropped the packet for - * routing-logical reasons. */ - - return NET_RX_SUCCESS; - -err_free: - kfree_skb(skb); -err_out: - return NET_RX_DROP; -} - /* This function returns true if the interface represented by ifindex is a * 802.11 wireless device */ bool is_wifi_iface(int ifindex) diff --combined send.c index 20f6e89,8ec33b0..d24702d --- a/send.c +++ b/send.c @@@ -20,7 -20,6 +20,7 @@@ */
#include "main.h" +#include "distributed-arp-table.h" #include "send.h" #include "routing.h" #include "translation-table.h" @@@ -46,13 -45,13 +46,13 @@@ int send_skb_packet(struct sk_buff *skb goto send_skb_err;
if (!(hard_iface->net_dev->flags & IFF_UP)) { - pr_warning("Interface %s is not up - can't send packet via that interface!\n", + pr_warn("Interface %s is not up - can't send packet via that interface!\n", hard_iface->net_dev->name); goto send_skb_err; }
/* push to the ethernet header. */ - if (my_skb_head_push(skb, sizeof(*ethhdr)) < 0) + if (my_skb_head_push(skb, ETH_HLEN) < 0) goto send_skb_err;
skb_reset_mac_header(skb); @@@ -88,7 -87,7 +88,7 @@@ static void realloc_packet_buffer(struc /* keep old buffer if kmalloc should fail */ if (new_buff) { memcpy(new_buff, hard_iface->packet_buff, - BATMAN_OGM_LEN); + BATMAN_OGM_HLEN);
kfree(hard_iface->packet_buff); hard_iface->packet_buff = new_buff; @@@ -102,13 -101,13 +102,13 @@@ static int prepare_packet_buffer(struc { int new_len;
- new_len = BATMAN_OGM_LEN + + new_len = BATMAN_OGM_HLEN + tt_len((uint8_t)atomic_read(&bat_priv->tt_local_changes));
/* if we have too many changes for one packet don't send any * and wait for the tt table request which will be fragmented */ if (new_len > hard_iface->soft_iface->mtu) - new_len = BATMAN_OGM_LEN; + new_len = BATMAN_OGM_HLEN;
realloc_packet_buffer(hard_iface, new_len);
@@@ -118,14 -117,14 +118,14 @@@ atomic_set(&bat_priv->tt_ogm_append_cnt, TT_OGM_APPEND_MAX);
return tt_changes_fill_buffer(bat_priv, - hard_iface->packet_buff + BATMAN_OGM_LEN, - hard_iface->packet_len - BATMAN_OGM_LEN); + hard_iface->packet_buff + BATMAN_OGM_HLEN, + hard_iface->packet_len - BATMAN_OGM_HLEN); }
static int reset_packet_buffer(struct bat_priv *bat_priv, struct hard_iface *hard_iface) { - realloc_packet_buffer(hard_iface, BATMAN_OGM_LEN); + realloc_packet_buffer(hard_iface, BATMAN_OGM_HLEN); return 0; }
@@@ -275,9 -274,6 +275,9 @@@ static void send_outstanding_bcast_pack if (atomic_read(&bat_priv->mesh_state) == MESH_DEACTIVATING) goto out;
+ if (dat_drop_broadcast_packet(bat_priv, forw_packet)) + goto out; + /* rebroadcast packet */ rcu_read_lock(); list_for_each_entry_rcu(hard_iface, &hardif_list, list) { @@@ -296,7 -292,7 +296,7 @@@ /* if we still have some more bcasts to send */ if (forw_packet->num_packets < 3) { _add_bcast_packet_to_list(bat_priv, forw_packet, - ((5 * HZ) / 1000)); + msecs_to_jiffies(5)); return; }