diff options
| author | Mauro Carvalho Chehab <[email protected]> | 2014-04-14 12:00:36 -0300 |
|---|---|---|
| committer | Mauro Carvalho Chehab <[email protected]> | 2014-04-14 12:00:36 -0300 |
| commit | 277a163c83d7ba93fba1e8980d29a9f8bfcfba6c (patch) | |
| tree | ccfd357d152292958957b6b8a993892e7a8cc95f /net/batman-adv/soft-interface.c | |
| parent | a83b93a7480441a47856dc9104bea970e84cda87 (diff) | |
| parent | c9eaa447e77efe77b7fa4c953bd62de8297fd6c5 (diff) | |
Merge tag 'v3.15-rc1' into patchwork
Linux 3.15-rc1
* tag 'v3.15-rc1': (12180 commits)
Linux 3.15-rc1
mm: Initialize error in shmem_file_aio_read()
cifs: Use min_t() when comparing "size_t" and "unsigned long"
sym53c8xx_2: Set DID_REQUEUE return code when aborting squeue
powerpc: Don't try to set LPCR unless we're in hypervisor mode
futex: update documentation for ordering guarantees
ceph: fix pr_fmt() redefinition
vti: don't allow to add the same tunnel twice
gre: don't allow to add the same tunnel twice
drivers: net: xen-netfront: fix array initialization bug
missing bits of "splice: fix racy pipe->buffers uses"
cifs: fix the race in cifs_writev()
ceph_sync_{,direct_}write: fix an oops on ceph_osdc_new_request() failure
pktgen: be friendly to LLTX devices
r8152: check RTL8152_UNPLUG
net: sun4i-emac: add promiscuous support
net/apne: replace IS_ERR and PTR_ERR with PTR_ERR_OR_ZERO
blackfin: cleanup board files
bf609: clock: drop unused clock bit set/clear functions
Blackfin: bf537: rename "CONFIG_ADT75"
...
Diffstat (limited to 'net/batman-adv/soft-interface.c')
| -rw-r--r-- | net/batman-adv/soft-interface.c | 48 |
1 files changed, 35 insertions, 13 deletions
diff --git a/net/batman-adv/soft-interface.c b/net/batman-adv/soft-interface.c index f82c267e1886..744a59b85e15 100644 --- a/net/batman-adv/soft-interface.c +++ b/net/batman-adv/soft-interface.c @@ -32,6 +32,7 @@ #include <linux/ethtool.h> #include <linux/etherdevice.h> #include <linux/if_vlan.h> +#include "multicast.h" #include "bridge_loop_avoidance.h" #include "network-coding.h" @@ -111,8 +112,8 @@ static int batadv_interface_set_mac_addr(struct net_device *dev, void *p) if (!is_valid_ether_addr(addr->sa_data)) return -EADDRNOTAVAIL; - memcpy(old_addr, dev->dev_addr, ETH_ALEN); - memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN); + ether_addr_copy(old_addr, dev->dev_addr); + ether_addr_copy(dev->dev_addr, addr->sa_data); /* only modify transtable if it has been initialized before */ if (atomic_read(&bat_priv->mesh_state) == BATADV_MESH_ACTIVE) { @@ -170,17 +171,19 @@ static int batadv_interface_tx(struct sk_buff *skb, unsigned short vid; uint32_t seqno; int gw_mode; + enum batadv_forw_mode forw_mode; + struct batadv_orig_node *mcast_single_orig = NULL; 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; + ethhdr = eth_hdr(skb); switch (ntohs(ethhdr->h_proto)) { case ETH_P_8021Q: - vhdr = (struct vlan_ethhdr *)skb->data; + vhdr = vlan_eth_hdr(skb); if (vhdr->h_vlan_encapsulated_proto != ethertype) break; @@ -194,7 +197,7 @@ static int batadv_interface_tx(struct sk_buff *skb, goto dropped; /* skb->data might have been reallocated by batadv_bla_tx() */ - ethhdr = (struct ethhdr *)skb->data; + ethhdr = eth_hdr(skb); /* Register the client MAC in the transtable */ if (!is_multicast_ether_addr(ethhdr->h_source)) { @@ -230,7 +233,7 @@ static int batadv_interface_tx(struct sk_buff *skb, /* skb->data may have been modified by * batadv_gw_dhcp_recipient_get() */ - ethhdr = (struct ethhdr *)skb->data; + ethhdr = eth_hdr(skb); /* if gw_mode is on, broadcast any non-DHCP message. * All the DHCP packets are going to be sent as unicast */ @@ -247,9 +250,19 @@ static int batadv_interface_tx(struct sk_buff *skb, * directed to a DHCP server */ goto dropped; - } send: + if (do_bcast && !is_broadcast_ether_addr(ethhdr->h_dest)) { + forw_mode = batadv_mcast_forw_mode(bat_priv, skb, + &mcast_single_orig); + if (forw_mode == BATADV_FORW_NONE) + goto dropped; + + if (forw_mode == BATADV_FORW_SINGLE) + do_bcast = false; + } + } + batadv_skb_set_priority(skb, 0); /* ethernet packet should be broadcasted */ @@ -279,8 +292,8 @@ send: /* hw address of first interface is the orig mac because only * this mac is known throughout the mesh */ - memcpy(bcast_packet->orig, - primary_if->net_dev->dev_addr, ETH_ALEN); + ether_addr_copy(bcast_packet->orig, + primary_if->net_dev->dev_addr); /* set broadcast sequence number */ seqno = atomic_inc_return(&bat_priv->bcast_seqno); @@ -301,6 +314,10 @@ send: if (ret) goto dropped; ret = batadv_send_skb_via_gw(bat_priv, skb, vid); + } else if (mcast_single_orig) { + ret = batadv_send_skb_unicast(bat_priv, skb, + BATADV_UNICAST, 0, + mcast_single_orig, vid); } else { if (batadv_dat_snoop_outgoing_arp_request(bat_priv, skb)) @@ -652,10 +669,7 @@ static void batadv_softif_destroy_finish(struct work_struct *work) } batadv_sysfs_del_meshif(soft_iface); - - rtnl_lock(); - unregister_netdevice(soft_iface); - rtnl_unlock(); + unregister_netdev(soft_iface); } /** @@ -692,6 +706,14 @@ static int batadv_softif_init_late(struct net_device *dev) #ifdef CONFIG_BATMAN_ADV_DAT atomic_set(&bat_priv->distributed_arp_table, 1); #endif +#ifdef CONFIG_BATMAN_ADV_MCAST + bat_priv->mcast.flags = BATADV_NO_FLAGS; + atomic_set(&bat_priv->multicast_mode, 1); + atomic_set(&bat_priv->mcast.num_disabled, 0); + atomic_set(&bat_priv->mcast.num_want_all_unsnoopables, 0); + atomic_set(&bat_priv->mcast.num_want_all_ipv4, 0); + atomic_set(&bat_priv->mcast.num_want_all_ipv6, 0); +#endif 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); |