Skip to content

Commit

Permalink
Merge tag 'batman-adv-for-davem' of git://git.open-mesh.org/linux-merge
Browse files Browse the repository at this point in the history
Included changes:
- set the protocol field in the skb structure according to the encapsulated
  payload
- make the gateway component send a uevent in case of "gw client mode"
  de-selection
- increment version number
- minor code rearrangement

Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
David S. Miller committed Aug 29, 2013
2 parents 80b17be + c6eaa3f commit cc328de
Show file tree
Hide file tree
Showing 13 changed files with 140 additions and 18 deletions.
32 changes: 17 additions & 15 deletions net/batman-adv/bat_iv_ogm.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,22 @@
#include "bat_algo.h"
#include "network-coding.h"


/**
* batadv_dup_status - duplicate status
* @BATADV_NO_DUP: the packet is a duplicate
* @BATADV_ORIG_DUP: OGM is a duplicate in the originator (but not for the
* neighbor)
* @BATADV_NEIGH_DUP: OGM is a duplicate for the neighbor
* @BATADV_PROTECTED: originator is currently protected (after reboot)
*/
enum batadv_dup_status {
BATADV_NO_DUP = 0,
BATADV_ORIG_DUP,
BATADV_NEIGH_DUP,
BATADV_PROTECTED,
};

/**
* batadv_ring_buffer_set - update the ring buffer with the given value
* @lq_recv: pointer to the ring buffer
Expand Down Expand Up @@ -71,21 +87,6 @@ static uint8_t batadv_ring_buffer_avg(const uint8_t lq_recv[])
return (uint8_t)(sum / count);
}

/*
* batadv_dup_status - duplicate status
* @BATADV_NO_DUP: the packet is a duplicate
* @BATADV_ORIG_DUP: OGM is a duplicate in the originator (but not for the
* neighbor)
* @BATADV_NEIGH_DUP: OGM is a duplicate for the neighbor
* @BATADV_PROTECTED: originator is currently protected (after reboot)
*/
enum batadv_dup_status {
BATADV_NO_DUP = 0,
BATADV_ORIG_DUP,
BATADV_NEIGH_DUP,
BATADV_PROTECTED,
};

static struct batadv_neigh_node *
batadv_iv_ogm_neigh_new(struct batadv_hard_iface *hard_iface,
const uint8_t *neigh_addr,
Expand Down Expand Up @@ -478,6 +479,7 @@ static void batadv_iv_ogm_aggregate_new(const unsigned char *packet_buff,
kfree(forw_packet_aggr);
goto out;
}
forw_packet_aggr->skb->priority = TC_PRIO_CONTROL;
skb_reserve(forw_packet_aggr->skb, ETH_HLEN);

skb_buff = skb_put(forw_packet_aggr->skb, packet_len);
Expand Down
27 changes: 27 additions & 0 deletions net/batman-adv/gateway_client.c
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,33 @@ batadv_gw_get_best_gw_node(struct batadv_priv *bat_priv)
return curr_gw;
}

/**
* batadv_gw_check_client_stop - check if client mode has been switched off
* @bat_priv: the bat priv with all the soft interface information
*
* This function assumes the caller has checked that the gw state *is actually
* changing*. This function is not supposed to be called when there is no state
* change.
*/
void batadv_gw_check_client_stop(struct batadv_priv *bat_priv)
{
struct batadv_gw_node *curr_gw;

if (atomic_read(&bat_priv->gw_mode) != BATADV_GW_MODE_CLIENT)
return;

curr_gw = batadv_gw_get_selected_gw_node(bat_priv);
if (!curr_gw)
return;

/* if batman-adv is switching the gw client mode off and a gateway was
* already selected, send a DEL uevent
*/
batadv_throw_uevent(bat_priv, BATADV_UEV_GW, BATADV_UEV_DEL, NULL);

batadv_gw_node_free_ref(curr_gw);
}

void batadv_gw_election(struct batadv_priv *bat_priv)
{
struct batadv_gw_node *curr_gw = NULL, *next_gw = NULL;
Expand Down
1 change: 1 addition & 0 deletions net/batman-adv/gateway_client.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#ifndef _NET_BATMAN_ADV_GATEWAY_CLIENT_H_
#define _NET_BATMAN_ADV_GATEWAY_CLIENT_H_

void batadv_gw_check_client_stop(struct batadv_priv *bat_priv);
void batadv_gw_deselect(struct batadv_priv *bat_priv);
void batadv_gw_election(struct batadv_priv *bat_priv);
struct batadv_orig_node *
Expand Down
1 change: 1 addition & 0 deletions net/batman-adv/icmp_socket.c
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,7 @@ static ssize_t batadv_socket_write(struct file *file, const char __user *buff,
goto out;
}

skb->priority = TC_PRIO_CONTROL;
skb_reserve(skb, ETH_HLEN);
icmp_packet = (struct batadv_icmp_packet_rr *)skb_put(skb, packet_len);

Expand Down
58 changes: 58 additions & 0 deletions net/batman-adv/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@

#include <linux/crc32c.h>
#include <linux/highmem.h>
#include <linux/if_vlan.h>
#include <net/ip.h>
#include <net/ipv6.h>
#include <net/dsfield.h>
#include "main.h"
#include "sysfs.h"
#include "debugfs.h"
Expand Down Expand Up @@ -249,6 +253,60 @@ batadv_seq_print_text_primary_if_get(struct seq_file *seq)
return primary_if;
}

/**
* batadv_skb_set_priority - sets skb priority according to packet content
* @skb: the packet to be sent
* @offset: offset to the packet content
*
* This function sets a value between 256 and 263 (802.1d priority), which
* can be interpreted by the cfg80211 or other drivers.
*/
void batadv_skb_set_priority(struct sk_buff *skb, int offset)
{
struct iphdr ip_hdr_tmp, *ip_hdr;
struct ipv6hdr ip6_hdr_tmp, *ip6_hdr;
struct ethhdr ethhdr_tmp, *ethhdr;
struct vlan_ethhdr *vhdr, vhdr_tmp;
u32 prio;

/* already set, do nothing */
if (skb->priority >= 256 && skb->priority <= 263)
return;

ethhdr = skb_header_pointer(skb, offset, sizeof(*ethhdr), &ethhdr_tmp);
if (!ethhdr)
return;

switch (ethhdr->h_proto) {
case htons(ETH_P_8021Q):
vhdr = skb_header_pointer(skb, offset + sizeof(*vhdr),
sizeof(*vhdr), &vhdr_tmp);
if (!vhdr)
return;
prio = ntohs(vhdr->h_vlan_TCI) & VLAN_PRIO_MASK;
prio = prio >> VLAN_PRIO_SHIFT;
break;
case htons(ETH_P_IP):
ip_hdr = skb_header_pointer(skb, offset + sizeof(*ethhdr),
sizeof(*ip_hdr), &ip_hdr_tmp);
if (!ip_hdr)
return;
prio = (ipv4_get_dsfield(ip_hdr) & 0xfc) >> 5;
break;
case htons(ETH_P_IPV6):
ip6_hdr = skb_header_pointer(skb, offset + sizeof(*ethhdr),
sizeof(*ip6_hdr), &ip6_hdr_tmp);
if (!ip6_hdr)
return;
prio = (ipv6_get_dsfield(ip6_hdr) & 0xfc) >> 5;
break;
default:
return;
}

skb->priority = prio + 256;
}

static int batadv_recv_unhandled_packet(struct sk_buff *skb,
struct batadv_hard_iface *recv_if)
{
Expand Down
3 changes: 2 additions & 1 deletion net/batman-adv/main.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
#define BATADV_DRIVER_DEVICE "batman-adv"

#ifndef BATADV_SOURCE_VERSION
#define BATADV_SOURCE_VERSION "2013.3.0"
#define BATADV_SOURCE_VERSION "2013.4.0"
#endif

/* B.A.T.M.A.N. parameters */
Expand Down Expand Up @@ -184,6 +184,7 @@ void batadv_mesh_free(struct net_device *soft_iface);
int batadv_is_my_mac(struct batadv_priv *bat_priv, const uint8_t *addr);
struct batadv_hard_iface *
batadv_seq_print_text_primary_if_get(struct seq_file *seq);
void batadv_skb_set_priority(struct sk_buff *skb, int offset);
int batadv_batman_skb_recv(struct sk_buff *skb, struct net_device *dev,
struct packet_type *ptype,
struct net_device *orig_dev);
Expand Down
20 changes: 19 additions & 1 deletion net/batman-adv/routing.c
Original file line number Diff line number Diff line change
Expand Up @@ -775,7 +775,7 @@ static int batadv_route_unicast_packet(struct sk_buff *skb,
struct batadv_neigh_node *neigh_node = NULL;
struct batadv_unicast_packet *unicast_packet;
struct ethhdr *ethhdr = eth_hdr(skb);
int res, ret = NET_RX_DROP;
int res, hdr_len, ret = NET_RX_DROP;
struct sk_buff *new_skb;

unicast_packet = (struct batadv_unicast_packet *)skb->data;
Expand Down Expand Up @@ -835,6 +835,22 @@ static int batadv_route_unicast_packet(struct sk_buff *skb,
/* decrement ttl */
unicast_packet->header.ttl--;

switch (unicast_packet->header.packet_type) {
case BATADV_UNICAST_4ADDR:
hdr_len = sizeof(struct batadv_unicast_4addr_packet);
break;
case BATADV_UNICAST:
hdr_len = sizeof(struct batadv_unicast_packet);
break;
default:
/* other packet types not supported - yet */
hdr_len = -1;
break;
}

if (hdr_len > 0)
batadv_skb_set_priority(skb, hdr_len);

res = batadv_send_skb_to_orig(skb, orig_node, recv_if);

/* translate transmit result into receive result */
Expand Down Expand Up @@ -1193,6 +1209,8 @@ int batadv_recv_bcast_packet(struct sk_buff *skb,
if (batadv_bla_check_bcast_duplist(bat_priv, skb))
goto out;

batadv_skb_set_priority(skb, sizeof(struct batadv_bcast_packet));

/* rebroadcast packet */
batadv_add_bcast_packet_to_list(bat_priv, skb, 1);

Expand Down
1 change: 0 additions & 1 deletion net/batman-adv/send.c
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,6 @@ int batadv_send_skb_packet(struct sk_buff *skb,
ethhdr->h_proto = __constant_htons(ETH_P_BATMAN);

skb_set_network_header(skb, ETH_HLEN);
skb->priority = TC_PRIO_CONTROL;
skb->protocol = __constant_htons(ETH_P_BATMAN);

skb->dev = hard_iface->net_dev;
Expand Down
2 changes: 2 additions & 0 deletions net/batman-adv/soft-interface.c
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,8 @@ static int batadv_interface_tx(struct sk_buff *skb,
*/
}

batadv_skb_set_priority(skb, 0);

/* ethernet packet should be broadcasted */
if (do_bcast) {
primary_if = batadv_primary_if_get_selected(bat_priv);
Expand Down
4 changes: 4 additions & 0 deletions net/batman-adv/sysfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -385,6 +385,10 @@ static ssize_t batadv_store_gw_mode(struct kobject *kobj,
curr_gw_mode_str, buff);

batadv_gw_deselect(bat_priv);
/* always call batadv_gw_check_client_stop() before changing the gateway
* state
*/
batadv_gw_check_client_stop(bat_priv);
atomic_set(&bat_priv->gw_mode, (unsigned int)gw_mode_tmp);
return count;
}
Expand Down
5 changes: 5 additions & 0 deletions net/batman-adv/translation-table.c
Original file line number Diff line number Diff line change
Expand Up @@ -1626,6 +1626,7 @@ batadv_tt_response_fill_table(uint16_t tt_len, uint8_t ttvn,
if (!skb)
goto out;

skb->priority = TC_PRIO_CONTROL;
skb_reserve(skb, ETH_HLEN);
tt_response = (struct batadv_tt_query_packet *)skb_put(skb, len);
tt_response->ttvn = ttvn;
Expand Down Expand Up @@ -1691,6 +1692,7 @@ static int batadv_send_tt_request(struct batadv_priv *bat_priv,
if (!skb)
goto out;

skb->priority = TC_PRIO_CONTROL;
skb_reserve(skb, ETH_HLEN);

tt_req_len = sizeof(*tt_request);
Expand Down Expand Up @@ -1788,6 +1790,7 @@ batadv_send_other_tt_response(struct batadv_priv *bat_priv,
if (!skb)
goto unlock;

skb->priority = TC_PRIO_CONTROL;
skb_reserve(skb, ETH_HLEN);
packet_pos = skb_put(skb, len);
tt_response = (struct batadv_tt_query_packet *)packet_pos;
Expand Down Expand Up @@ -1906,6 +1909,7 @@ batadv_send_my_tt_response(struct batadv_priv *bat_priv,
if (!skb)
goto unlock;

skb->priority = TC_PRIO_CONTROL;
skb_reserve(skb, ETH_HLEN);
packet_pos = skb_put(skb, len);
tt_response = (struct batadv_tt_query_packet *)packet_pos;
Expand Down Expand Up @@ -2240,6 +2244,7 @@ static void batadv_send_roam_adv(struct batadv_priv *bat_priv, uint8_t *client,
if (!skb)
goto out;

skb->priority = TC_PRIO_CONTROL;
skb_reserve(skb, ETH_HLEN);

roam_adv_packet = (struct batadv_roam_adv_packet *)skb_put(skb, len);
Expand Down
2 changes: 2 additions & 0 deletions net/batman-adv/unicast.c
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,8 @@ int batadv_frag_send_skb(struct sk_buff *skb, struct batadv_priv *bat_priv,
frag_skb = dev_alloc_skb(data_len - (data_len / 2) + ucf_hdr_len);
if (!frag_skb)
goto dropped;

skb->priority = TC_PRIO_CONTROL;
skb_reserve(frag_skb, ucf_hdr_len);

unicast_packet = (struct batadv_unicast_packet *)skb->data;
Expand Down
2 changes: 2 additions & 0 deletions net/batman-adv/vis.c
Original file line number Diff line number Diff line change
Expand Up @@ -397,6 +397,7 @@ batadv_add_packet(struct batadv_priv *bat_priv,
kfree(info);
return NULL;
}
info->skb_packet->priority = TC_PRIO_CONTROL;
skb_reserve(info->skb_packet, ETH_HLEN);
packet = (struct batadv_vis_packet *)skb_put(info->skb_packet, len);

Expand Down Expand Up @@ -861,6 +862,7 @@ int batadv_vis_init(struct batadv_priv *bat_priv)
if (!bat_priv->vis.my_info->skb_packet)
goto free_info;

bat_priv->vis.my_info->skb_packet->priority = TC_PRIO_CONTROL;
skb_reserve(bat_priv->vis.my_info->skb_packet, ETH_HLEN);
tmp_skb = bat_priv->vis.my_info->skb_packet;
packet = (struct batadv_vis_packet *)skb_put(tmp_skb, sizeof(*packet));
Expand Down

0 comments on commit cc328de

Please sign in to comment.