diff options
author | Scott Wood <scottwood@freescale.com> | 2014-04-07 23:49:35 (GMT) |
---|---|---|
committer | Scott Wood <scottwood@freescale.com> | 2014-04-07 23:49:35 (GMT) |
commit | 62b8c978ee6b8d135d9e7953221de58000dba986 (patch) | |
tree | 683b04b2e627f6710c22c151b23c8cc9a165315e /net/batman-adv/soft-interface.c | |
parent | 78fd82238d0e5716578c326404184a27ba67fd6e (diff) | |
download | linux-fsl-qoriq-62b8c978ee6b8d135d9e7953221de58000dba986.tar.xz |
Rewind v3.13-rc3+ (78fd82238d0e5716) to v3.12
Diffstat (limited to 'net/batman-adv/soft-interface.c')
-rw-r--r-- | net/batman-adv/soft-interface.c | 269 |
1 files changed, 28 insertions, 241 deletions
diff --git a/net/batman-adv/soft-interface.c b/net/batman-adv/soft-interface.c index 36f0508..813db4e 100644 --- a/net/batman-adv/soft-interface.c +++ b/net/batman-adv/soft-interface.c @@ -34,6 +34,8 @@ #include <linux/ethtool.h> #include <linux/etherdevice.h> #include <linux/if_vlan.h> +#include <linux/if_ether.h> +#include "unicast.h" #include "bridge_loop_avoidance.h" #include "network-coding.h" @@ -118,10 +120,9 @@ static int batadv_interface_set_mac_addr(struct net_device *dev, void *p) /* only modify transtable if it has been initialized before */ if (atomic_read(&bat_priv->mesh_state) == BATADV_MESH_ACTIVE) { - batadv_tt_local_remove(bat_priv, old_addr, BATADV_NO_FLAGS, + batadv_tt_local_remove(bat_priv, old_addr, "mac address changed", false); - batadv_tt_local_add(dev, addr->sa_data, BATADV_NO_FLAGS, - BATADV_NULL_IFINDEX); + batadv_tt_local_add(dev, addr->sa_data, BATADV_NULL_IFINDEX); } return 0; @@ -138,48 +139,36 @@ static int batadv_interface_change_mtu(struct net_device *dev, int new_mtu) return 0; } -/** - * batadv_interface_set_rx_mode - set the rx mode of a device - * @dev: registered network device to modify - * - * We do not actually need to set any rx filters for the virtual batman - * soft interface. However a dummy handler enables a user to set static - * multicast listeners for instance. - */ -static void batadv_interface_set_rx_mode(struct net_device *dev) -{ -} - static int batadv_interface_tx(struct sk_buff *skb, struct net_device *soft_iface) { - struct ethhdr *ethhdr; + struct ethhdr *ethhdr = (struct ethhdr *)skb->data; struct batadv_priv *bat_priv = netdev_priv(soft_iface); struct batadv_hard_iface *primary_if = NULL; struct batadv_bcast_packet *bcast_packet; - __be16 ethertype = htons(ETH_P_BATMAN); + struct vlan_ethhdr *vhdr; + __be16 ethertype = __constant_htons(ETH_P_BATMAN); static const uint8_t stp_addr[ETH_ALEN] = {0x01, 0x80, 0xC2, 0x00, 0x00, 0x00}; static const uint8_t ectp_addr[ETH_ALEN] = {0xCF, 0x00, 0x00, 0x00, 0x00, 0x00}; - struct vlan_ethhdr *vhdr; unsigned int header_len = 0; int data_len = skb->len, ret; - unsigned long brd_delay = 1; - bool do_bcast = false, client_added; - unsigned short vid; + unsigned short vid __maybe_unused = BATADV_NO_FLAGS; + bool do_bcast = false; uint32_t seqno; + unsigned long brd_delay = 1; if (atomic_read(&bat_priv->mesh_state) != BATADV_MESH_ACTIVE) goto dropped; soft_iface->trans_start = jiffies; - vid = batadv_get_vid(skb, 0); - ethhdr = (struct ethhdr *)skb->data; switch (ntohs(ethhdr->h_proto)) { case ETH_P_8021Q: vhdr = (struct vlan_ethhdr *)skb->data; + vid = ntohs(vhdr->h_vlan_TCI) & VLAN_VID_MASK; + vid |= BATADV_VLAN_HAS_TAG; if (vhdr->h_vlan_encapsulated_proto != ethertype) break; @@ -196,12 +185,8 @@ static int batadv_interface_tx(struct sk_buff *skb, ethhdr = (struct ethhdr *)skb->data; /* Register the client MAC in the transtable */ - if (!is_multicast_ether_addr(ethhdr->h_source)) { - client_added = batadv_tt_local_add(soft_iface, ethhdr->h_source, - vid, skb->skb_iif); - if (!client_added) - goto dropped; - } + if (!is_multicast_ether_addr(ethhdr->h_source)) + batadv_tt_local_add(soft_iface, ethhdr->h_source, skb->skb_iif); /* don't accept stp packets. STP does not help in meshes. * better use the bridge loop avoidance ... @@ -301,12 +286,8 @@ static int batadv_interface_tx(struct sk_buff *skb, batadv_dat_snoop_outgoing_arp_reply(bat_priv, skb); - if (is_multicast_ether_addr(ethhdr->h_dest)) - ret = batadv_send_skb_via_gw(bat_priv, skb, vid); - else - ret = batadv_send_skb_via_tt(bat_priv, skb, vid); - - if (ret == NET_XMIT_DROP) + ret = batadv_unicast_send_skb(bat_priv, skb); + if (ret != 0) goto dropped_freed; } @@ -328,12 +309,12 @@ void batadv_interface_rx(struct net_device *soft_iface, struct sk_buff *skb, struct batadv_hard_iface *recv_if, int hdr_size, struct batadv_orig_node *orig_node) { - struct batadv_header *batadv_header = (struct batadv_header *)skb->data; struct batadv_priv *bat_priv = netdev_priv(soft_iface); - __be16 ethertype = htons(ETH_P_BATMAN); - struct vlan_ethhdr *vhdr; struct ethhdr *ethhdr; - unsigned short vid; + struct vlan_ethhdr *vhdr; + struct batadv_header *batadv_header = (struct batadv_header *)skb->data; + unsigned short vid __maybe_unused = BATADV_NO_FLAGS; + __be16 ethertype = __constant_htons(ETH_P_BATMAN); bool is_bcast; is_bcast = (batadv_header->packet_type == BATADV_BCAST); @@ -345,12 +326,13 @@ void batadv_interface_rx(struct net_device *soft_iface, skb_pull_rcsum(skb, hdr_size); skb_reset_mac_header(skb); - vid = batadv_get_vid(skb, hdr_size); ethhdr = eth_hdr(skb); switch (ntohs(ethhdr->h_proto)) { case ETH_P_8021Q: vhdr = (struct vlan_ethhdr *)skb->data; + vid = ntohs(vhdr->h_vlan_TCI) & VLAN_VID_MASK; + vid |= BATADV_VLAN_HAS_TAG; if (vhdr->h_vlan_encapsulated_proto != ethertype) break; @@ -386,10 +368,9 @@ void batadv_interface_rx(struct net_device *soft_iface, if (orig_node) batadv_tt_add_temporary_global_entry(bat_priv, orig_node, - ethhdr->h_source, vid); + ethhdr->h_source); - if (batadv_is_ap_isolated(bat_priv, ethhdr->h_source, ethhdr->h_dest, - vid)) + if (batadv_is_ap_isolated(bat_priv, ethhdr->h_source, ethhdr->h_dest)) goto dropped; netif_rx(skb); @@ -401,177 +382,6 @@ out: return; } -/** - * batadv_softif_vlan_free_ref - decrease the vlan object refcounter and - * possibly free it - * @softif_vlan: the vlan object to release - */ -void batadv_softif_vlan_free_ref(struct batadv_softif_vlan *softif_vlan) -{ - if (atomic_dec_and_test(&softif_vlan->refcount)) - kfree_rcu(softif_vlan, rcu); -} - -/** - * batadv_softif_vlan_get - get the vlan object for a specific vid - * @bat_priv: the bat priv with all the soft interface information - * @vid: the identifier of the vlan object to retrieve - * - * Returns the private data of the vlan matching the vid passed as argument or - * NULL otherwise. The refcounter of the returned object is incremented by 1. - */ -struct batadv_softif_vlan *batadv_softif_vlan_get(struct batadv_priv *bat_priv, - unsigned short vid) -{ - struct batadv_softif_vlan *vlan_tmp, *vlan = NULL; - - rcu_read_lock(); - hlist_for_each_entry_rcu(vlan_tmp, &bat_priv->softif_vlan_list, list) { - if (vlan_tmp->vid != vid) - continue; - - if (!atomic_inc_not_zero(&vlan_tmp->refcount)) - continue; - - vlan = vlan_tmp; - break; - } - rcu_read_unlock(); - - return vlan; -} - -/** - * batadv_create_vlan - allocate the needed resources for a new vlan - * @bat_priv: the bat priv with all the soft interface information - * @vid: the VLAN identifier - * - * Returns 0 on success, a negative error otherwise. - */ -int batadv_softif_create_vlan(struct batadv_priv *bat_priv, unsigned short vid) -{ - struct batadv_softif_vlan *vlan; - int err; - - vlan = batadv_softif_vlan_get(bat_priv, vid); - if (vlan) { - batadv_softif_vlan_free_ref(vlan); - return -EEXIST; - } - - vlan = kzalloc(sizeof(*vlan), GFP_ATOMIC); - if (!vlan) - return -ENOMEM; - - vlan->vid = vid; - atomic_set(&vlan->refcount, 1); - - atomic_set(&vlan->ap_isolation, 0); - - err = batadv_sysfs_add_vlan(bat_priv->soft_iface, vlan); - if (err) { - kfree(vlan); - return err; - } - - /* add a new TT local entry. This one will be marked with the NOPURGE - * flag - */ - batadv_tt_local_add(bat_priv->soft_iface, - bat_priv->soft_iface->dev_addr, vid, - BATADV_NULL_IFINDEX); - - spin_lock_bh(&bat_priv->softif_vlan_list_lock); - hlist_add_head_rcu(&vlan->list, &bat_priv->softif_vlan_list); - spin_unlock_bh(&bat_priv->softif_vlan_list_lock); - - return 0; -} - -/** - * batadv_softif_destroy_vlan - remove and destroy a softif_vlan object - * @bat_priv: the bat priv with all the soft interface information - * @vlan: the object to remove - */ -static void batadv_softif_destroy_vlan(struct batadv_priv *bat_priv, - struct batadv_softif_vlan *vlan) -{ - spin_lock_bh(&bat_priv->softif_vlan_list_lock); - hlist_del_rcu(&vlan->list); - spin_unlock_bh(&bat_priv->softif_vlan_list_lock); - - batadv_sysfs_del_vlan(bat_priv, vlan); - - /* explicitly remove the associated TT local entry because it is marked - * with the NOPURGE flag - */ - batadv_tt_local_remove(bat_priv, bat_priv->soft_iface->dev_addr, - vlan->vid, "vlan interface destroyed", false); - - batadv_softif_vlan_free_ref(vlan); -} - -/** - * batadv_interface_add_vid - ndo_add_vid API implementation - * @dev: the netdev of the mesh interface - * @vid: identifier of the new vlan - * - * Set up all the internal structures for handling the new vlan on top of the - * mesh interface - * - * Returns 0 on success or a negative error code in case of failure. - */ -static int batadv_interface_add_vid(struct net_device *dev, __be16 proto, - unsigned short vid) -{ - struct batadv_priv *bat_priv = netdev_priv(dev); - - /* only 802.1Q vlans are supported. - * batman-adv does not know how to handle other types - */ - if (proto != htons(ETH_P_8021Q)) - return -EINVAL; - - vid |= BATADV_VLAN_HAS_TAG; - - return batadv_softif_create_vlan(bat_priv, vid); -} - -/** - * batadv_interface_kill_vid - ndo_kill_vid API implementation - * @dev: the netdev of the mesh interface - * @vid: identifier of the deleted vlan - * - * Destroy all the internal structures used to handle the vlan identified by vid - * on top of the mesh interface - * - * Returns 0 on success, -EINVAL if the specified prototype is not ETH_P_8021Q - * or -ENOENT if the specified vlan id wasn't registered. - */ -static int batadv_interface_kill_vid(struct net_device *dev, __be16 proto, - unsigned short vid) -{ - struct batadv_priv *bat_priv = netdev_priv(dev); - struct batadv_softif_vlan *vlan; - - /* only 802.1Q vlans are supported. batman-adv does not know how to - * handle other types - */ - if (proto != htons(ETH_P_8021Q)) - return -EINVAL; - - vlan = batadv_softif_vlan_get(bat_priv, vid | BATADV_VLAN_HAS_TAG); - if (!vlan) - return -ENOENT; - - batadv_softif_destroy_vlan(bat_priv, vlan); - - /* finally free the vlan object */ - batadv_softif_vlan_free_ref(vlan); - - return 0; -} - /* batman-adv network devices have devices nesting below it and are a special * "super class" of normal network devices; split their locks off into a * separate class since they always nest. @@ -611,7 +421,6 @@ static void batadv_set_lockdep_class(struct net_device *dev) */ static void batadv_softif_destroy_finish(struct work_struct *work) { - struct batadv_softif_vlan *vlan; struct batadv_priv *bat_priv; struct net_device *soft_iface; @@ -619,13 +428,6 @@ static void batadv_softif_destroy_finish(struct work_struct *work) cleanup_work); soft_iface = bat_priv->soft_iface; - /* destroy the "untagged" VLAN */ - vlan = batadv_softif_vlan_get(bat_priv, BATADV_NO_FLAGS); - if (vlan) { - batadv_softif_destroy_vlan(bat_priv, vlan); - batadv_softif_vlan_free_ref(vlan); - } - batadv_sysfs_del_meshif(soft_iface); rtnl_lock(); @@ -642,7 +444,6 @@ static void batadv_softif_destroy_finish(struct work_struct *work) static int batadv_softif_init_late(struct net_device *dev) { struct batadv_priv *bat_priv; - uint32_t random_seqno; int ret; size_t cnt_len = sizeof(uint64_t) * BATADV_CNT_NUM; @@ -667,17 +468,17 @@ static int batadv_softif_init_late(struct net_device *dev) #ifdef CONFIG_BATMAN_ADV_DAT atomic_set(&bat_priv->distributed_arp_table, 1); #endif + atomic_set(&bat_priv->ap_isolation, 0); + atomic_set(&bat_priv->vis_mode, BATADV_VIS_TYPE_CLIENT_UPDATE); atomic_set(&bat_priv->gw_mode, BATADV_GW_MODE_OFF); atomic_set(&bat_priv->gw_sel_class, 20); - atomic_set(&bat_priv->gw.bandwidth_down, 100); - atomic_set(&bat_priv->gw.bandwidth_up, 20); + atomic_set(&bat_priv->gw_bandwidth, 41); atomic_set(&bat_priv->orig_interval, 1000); atomic_set(&bat_priv->hop_penalty, 30); #ifdef CONFIG_BATMAN_ADV_DEBUG atomic_set(&bat_priv->log_level, 0); #endif atomic_set(&bat_priv->fragmentation, 1); - atomic_set(&bat_priv->packet_size_max, ETH_DATA_LEN); atomic_set(&bat_priv->bcast_queue_left, BATADV_BCAST_QUEUE_LEN); atomic_set(&bat_priv->batman_queue_left, BATADV_BATMAN_QUEUE_LEN); @@ -692,10 +493,6 @@ static int batadv_softif_init_late(struct net_device *dev) bat_priv->tt.last_changeset = NULL; bat_priv->tt.last_changeset_len = 0; - /* randomize initial seqno to avoid collision */ - get_random_bytes(&random_seqno, sizeof(random_seqno)); - atomic_set(&bat_priv->frag_seqno, random_seqno); - bat_priv->primary_if = NULL; bat_priv->num_ifaces = 0; @@ -781,11 +578,8 @@ static const struct net_device_ops batadv_netdev_ops = { .ndo_open = batadv_interface_open, .ndo_stop = batadv_interface_release, .ndo_get_stats = batadv_interface_stats, - .ndo_vlan_rx_add_vid = batadv_interface_add_vid, - .ndo_vlan_rx_kill_vid = batadv_interface_kill_vid, .ndo_set_mac_address = batadv_interface_set_mac_addr, .ndo_change_mtu = batadv_interface_change_mtu, - .ndo_set_rx_mode = batadv_interface_set_rx_mode, .ndo_start_xmit = batadv_interface_tx, .ndo_validate_addr = eth_validate_addr, .ndo_add_slave = batadv_softif_slave_add, @@ -822,7 +616,6 @@ static void batadv_softif_init_early(struct net_device *dev) dev->netdev_ops = &batadv_netdev_ops; dev->destructor = batadv_softif_free; - dev->features |= NETIF_F_HW_VLAN_CTAG_FILTER; dev->tx_queue_len = 0; /* can't call min_mtu, because the needed variables @@ -830,7 +623,7 @@ static void batadv_softif_init_early(struct net_device *dev) */ dev->mtu = ETH_DATA_LEN; /* reserve more space in the skbuff for our header */ - dev->hard_header_len = batadv_max_header_len(); + dev->hard_header_len = BATADV_HEADER_LEN; /* generate random address */ eth_hw_addr_random(dev); @@ -967,12 +760,6 @@ static const struct { { "mgmt_tx_bytes" }, { "mgmt_rx" }, { "mgmt_rx_bytes" }, - { "frag_tx" }, - { "frag_tx_bytes" }, - { "frag_rx" }, - { "frag_rx_bytes" }, - { "frag_fwd" }, - { "frag_fwd_bytes" }, { "tt_request_tx" }, { "tt_request_rx" }, { "tt_response_tx" }, |