diff options
Diffstat (limited to 'net/batman-adv/soft-interface.c')
-rw-r--r-- | net/batman-adv/soft-interface.c | 66 |
1 files changed, 30 insertions, 36 deletions
diff --git a/net/batman-adv/soft-interface.c b/net/batman-adv/soft-interface.c index d5aa60999e8..3e2f91ffa4e 100644 --- a/net/batman-adv/soft-interface.c +++ b/net/batman-adv/soft-interface.c @@ -30,6 +30,7 @@ #include "gateway_common.h" #include "gateway_client.h" #include "bat_sysfs.h" +#include "originator.h" #include <linux/slab.h> #include <linux/ethtool.h> #include <linux/etherdevice.h> @@ -123,8 +124,7 @@ static struct softif_neigh_vid *softif_neigh_vid_get(struct bat_priv *bat_priv, goto out; } - softif_neigh_vid = kzalloc(sizeof(struct softif_neigh_vid), - GFP_ATOMIC); + softif_neigh_vid = kzalloc(sizeof(*softif_neigh_vid), GFP_ATOMIC); if (!softif_neigh_vid) goto out; @@ -146,7 +146,7 @@ out: } static struct softif_neigh *softif_neigh_get(struct bat_priv *bat_priv, - uint8_t *addr, short vid) + const uint8_t *addr, short vid) { struct softif_neigh_vid *softif_neigh_vid; struct softif_neigh *softif_neigh = NULL; @@ -170,7 +170,7 @@ static struct softif_neigh *softif_neigh_get(struct bat_priv *bat_priv, goto unlock; } - softif_neigh = kzalloc(sizeof(struct softif_neigh), GFP_ATOMIC); + softif_neigh = kzalloc(sizeof(*softif_neigh), GFP_ATOMIC); if (!softif_neigh) goto unlock; @@ -242,7 +242,8 @@ static void softif_neigh_vid_select(struct bat_priv *bat_priv, if (new_neigh && !atomic_inc_not_zero(&new_neigh->refcount)) new_neigh = NULL; - curr_neigh = softif_neigh_vid->softif_neigh; + curr_neigh = rcu_dereference_protected(softif_neigh_vid->softif_neigh, + 1); rcu_assign_pointer(softif_neigh_vid->softif_neigh, new_neigh); if ((curr_neigh) && (!new_neigh)) @@ -380,7 +381,7 @@ void softif_neigh_purge(struct bat_priv *bat_priv) struct softif_neigh *softif_neigh, *curr_softif_neigh; struct softif_neigh_vid *softif_neigh_vid; struct hlist_node *node, *node_tmp, *node_tmp2; - char do_deselect; + int do_deselect; rcu_read_lock(); hlist_for_each_entry_rcu(softif_neigh_vid, node, @@ -534,7 +535,7 @@ static int interface_set_mac_addr(struct net_device *dev, void *p) /* only modify transtable if it has been initialised before */ if (atomic_read(&bat_priv->mesh_state) == MESH_ACTIVE) { tt_local_remove(bat_priv, dev->dev_addr, - "mac address changed"); + "mac address changed", false); tt_local_add(dev, addr->sa_data); } @@ -553,7 +554,7 @@ static int interface_change_mtu(struct net_device *dev, int new_mtu) return 0; } -int interface_tx(struct sk_buff *skb, struct net_device *soft_iface) +static int interface_tx(struct sk_buff *skb, struct net_device *soft_iface) { struct ethhdr *ethhdr = (struct ethhdr *)skb->data; struct bat_priv *bat_priv = netdev_priv(soft_iface); @@ -561,6 +562,7 @@ int interface_tx(struct sk_buff *skb, struct net_device *soft_iface) struct bcast_packet *bcast_packet; struct vlan_ethhdr *vhdr; struct softif_neigh *curr_softif_neigh = NULL; + struct orig_node *orig_node = NULL; int data_len = skb->len, ret; short vid = -1; bool do_bcast = false; @@ -592,11 +594,13 @@ int interface_tx(struct sk_buff *skb, struct net_device *soft_iface) if (curr_softif_neigh) goto dropped; - /* TODO: check this for locks */ + /* Register the client MAC in the transtable */ tt_local_add(soft_iface, ethhdr->h_source); - if (is_multicast_ether_addr(ethhdr->h_dest)) { - ret = gw_is_target(bat_priv, skb); + orig_node = transtable_search(bat_priv, ethhdr->h_dest); + if (is_multicast_ether_addr(ethhdr->h_dest) || + (orig_node && orig_node->gw_flags)) { + ret = gw_is_target(bat_priv, skb, orig_node); if (ret < 0) goto dropped; @@ -611,7 +615,7 @@ int interface_tx(struct sk_buff *skb, struct net_device *soft_iface) if (!primary_if) goto dropped; - if (my_skb_head_push(skb, sizeof(struct bcast_packet)) < 0) + if (my_skb_head_push(skb, sizeof(*bcast_packet)) < 0) goto dropped; bcast_packet = (struct bcast_packet *)skb->data; @@ -630,7 +634,7 @@ int interface_tx(struct sk_buff *skb, struct net_device *soft_iface) bcast_packet->seqno = htonl(atomic_inc_return(&bat_priv->bcast_seqno)); - add_bcast_packet_to_list(bat_priv, skb); + add_bcast_packet_to_list(bat_priv, skb, 1); /* a copy is stored in the bcast list, therefore removing * the original skb. */ @@ -656,6 +660,8 @@ end: softif_neigh_free_ref(curr_softif_neigh); if (primary_if) hardif_free_ref(primary_if); + if (orig_node) + orig_node_free_ref(orig_node); return NETDEV_TX_OK; } @@ -744,7 +750,6 @@ out: return; } -#ifdef HAVE_NET_DEVICE_OPS static const struct net_device_ops bat_netdev_ops = { .ndo_open = interface_open, .ndo_stop = interface_release, @@ -754,7 +759,6 @@ static const struct net_device_ops bat_netdev_ops = { .ndo_start_xmit = interface_tx, .ndo_validate_addr = eth_validate_addr }; -#endif static void interface_setup(struct net_device *dev) { @@ -763,16 +767,7 @@ static void interface_setup(struct net_device *dev) ether_setup(dev); -#ifdef HAVE_NET_DEVICE_OPS dev->netdev_ops = &bat_netdev_ops; -#else - dev->open = interface_open; - dev->stop = interface_release; - dev->get_stats = interface_stats; - dev->set_mac_address = interface_set_mac_addr; - dev->change_mtu = interface_change_mtu; - dev->hard_start_xmit = interface_tx; -#endif dev->destructor = free_netdev; dev->tx_queue_len = 0; @@ -790,17 +785,16 @@ static void interface_setup(struct net_device *dev) SET_ETHTOOL_OPS(dev, &bat_ethtool_ops); - memset(priv, 0, sizeof(struct bat_priv)); + memset(priv, 0, sizeof(*priv)); } -struct net_device *softif_create(char *name) +struct net_device *softif_create(const char *name) { struct net_device *soft_iface; struct bat_priv *bat_priv; int ret; - soft_iface = alloc_netdev(sizeof(struct bat_priv) , name, - interface_setup); + soft_iface = alloc_netdev(sizeof(*bat_priv), name, interface_setup); if (!soft_iface) { pr_err("Unable to allocate the batman interface: %s\n", name); @@ -831,7 +825,13 @@ struct net_device *softif_create(char *name) atomic_set(&bat_priv->mesh_state, MESH_INACTIVE); atomic_set(&bat_priv->bcast_seqno, 1); - atomic_set(&bat_priv->tt_local_changed, 0); + atomic_set(&bat_priv->ttvn, 0); + atomic_set(&bat_priv->tt_local_changes, 0); + atomic_set(&bat_priv->tt_ogm_append_cnt, 0); + + bat_priv->tt_buff = NULL; + bat_priv->tt_buff_len = 0; + bat_priv->tt_poss_change = false; bat_priv->primary_if = NULL; bat_priv->num_ifaces = 0; @@ -872,15 +872,10 @@ void softif_destroy(struct net_device *soft_iface) unregister_netdevice(soft_iface); } -int softif_is_valid(struct net_device *net_dev) +int softif_is_valid(const struct net_device *net_dev) { -#ifdef HAVE_NET_DEVICE_OPS if (net_dev->netdev_ops->ndo_start_xmit == interface_tx) return 1; -#else - if (net_dev->hard_start_xmit == interface_tx) - return 1; -#endif return 0; } @@ -924,4 +919,3 @@ static u32 bat_get_link(struct net_device *dev) { return 1; } - |