Commit cc328dea authored by David S. Miller's avatar David S. Miller

Merge tag 'batman-adv-for-davem' of git://git.open-mesh.org/linux-merge

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: default avatarDavid S. Miller <davem@davemloft.net>
parents 80b17be7 c6eaa3f0
...@@ -28,6 +28,22 @@ ...@@ -28,6 +28,22 @@
#include "bat_algo.h" #include "bat_algo.h"
#include "network-coding.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 * batadv_ring_buffer_set - update the ring buffer with the given value
* @lq_recv: pointer to the ring buffer * @lq_recv: pointer to the ring buffer
...@@ -71,21 +87,6 @@ static uint8_t batadv_ring_buffer_avg(const uint8_t lq_recv[]) ...@@ -71,21 +87,6 @@ static uint8_t batadv_ring_buffer_avg(const uint8_t lq_recv[])
return (uint8_t)(sum / count); 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 * static struct batadv_neigh_node *
batadv_iv_ogm_neigh_new(struct batadv_hard_iface *hard_iface, batadv_iv_ogm_neigh_new(struct batadv_hard_iface *hard_iface,
const uint8_t *neigh_addr, const uint8_t *neigh_addr,
...@@ -478,6 +479,7 @@ static void batadv_iv_ogm_aggregate_new(const unsigned char *packet_buff, ...@@ -478,6 +479,7 @@ static void batadv_iv_ogm_aggregate_new(const unsigned char *packet_buff,
kfree(forw_packet_aggr); kfree(forw_packet_aggr);
goto out; goto out;
} }
forw_packet_aggr->skb->priority = TC_PRIO_CONTROL;
skb_reserve(forw_packet_aggr->skb, ETH_HLEN); skb_reserve(forw_packet_aggr->skb, ETH_HLEN);
skb_buff = skb_put(forw_packet_aggr->skb, packet_len); skb_buff = skb_put(forw_packet_aggr->skb, packet_len);
......
...@@ -190,6 +190,33 @@ batadv_gw_get_best_gw_node(struct batadv_priv *bat_priv) ...@@ -190,6 +190,33 @@ batadv_gw_get_best_gw_node(struct batadv_priv *bat_priv)
return curr_gw; 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) void batadv_gw_election(struct batadv_priv *bat_priv)
{ {
struct batadv_gw_node *curr_gw = NULL, *next_gw = NULL; struct batadv_gw_node *curr_gw = NULL, *next_gw = NULL;
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#ifndef _NET_BATMAN_ADV_GATEWAY_CLIENT_H_ #ifndef _NET_BATMAN_ADV_GATEWAY_CLIENT_H_
#define _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_deselect(struct batadv_priv *bat_priv);
void batadv_gw_election(struct batadv_priv *bat_priv); void batadv_gw_election(struct batadv_priv *bat_priv);
struct batadv_orig_node * struct batadv_orig_node *
......
...@@ -183,6 +183,7 @@ static ssize_t batadv_socket_write(struct file *file, const char __user *buff, ...@@ -183,6 +183,7 @@ static ssize_t batadv_socket_write(struct file *file, const char __user *buff,
goto out; goto out;
} }
skb->priority = TC_PRIO_CONTROL;
skb_reserve(skb, ETH_HLEN); skb_reserve(skb, ETH_HLEN);
icmp_packet = (struct batadv_icmp_packet_rr *)skb_put(skb, packet_len); icmp_packet = (struct batadv_icmp_packet_rr *)skb_put(skb, packet_len);
......
...@@ -19,6 +19,10 @@ ...@@ -19,6 +19,10 @@
#include <linux/crc32c.h> #include <linux/crc32c.h>
#include <linux/highmem.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 "main.h"
#include "sysfs.h" #include "sysfs.h"
#include "debugfs.h" #include "debugfs.h"
...@@ -249,6 +253,60 @@ batadv_seq_print_text_primary_if_get(struct seq_file *seq) ...@@ -249,6 +253,60 @@ batadv_seq_print_text_primary_if_get(struct seq_file *seq)
return primary_if; 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, static int batadv_recv_unhandled_packet(struct sk_buff *skb,
struct batadv_hard_iface *recv_if) struct batadv_hard_iface *recv_if)
{ {
......
...@@ -26,7 +26,7 @@ ...@@ -26,7 +26,7 @@
#define BATADV_DRIVER_DEVICE "batman-adv" #define BATADV_DRIVER_DEVICE "batman-adv"
#ifndef BATADV_SOURCE_VERSION #ifndef BATADV_SOURCE_VERSION
#define BATADV_SOURCE_VERSION "2013.3.0" #define BATADV_SOURCE_VERSION "2013.4.0"
#endif #endif
/* B.A.T.M.A.N. parameters */ /* B.A.T.M.A.N. parameters */
...@@ -184,6 +184,7 @@ void batadv_mesh_free(struct net_device *soft_iface); ...@@ -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); int batadv_is_my_mac(struct batadv_priv *bat_priv, const uint8_t *addr);
struct batadv_hard_iface * struct batadv_hard_iface *
batadv_seq_print_text_primary_if_get(struct seq_file *seq); 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, int batadv_batman_skb_recv(struct sk_buff *skb, struct net_device *dev,
struct packet_type *ptype, struct packet_type *ptype,
struct net_device *orig_dev); struct net_device *orig_dev);
......
...@@ -775,7 +775,7 @@ static int batadv_route_unicast_packet(struct sk_buff *skb, ...@@ -775,7 +775,7 @@ static int batadv_route_unicast_packet(struct sk_buff *skb,
struct batadv_neigh_node *neigh_node = NULL; struct batadv_neigh_node *neigh_node = NULL;
struct batadv_unicast_packet *unicast_packet; struct batadv_unicast_packet *unicast_packet;
struct ethhdr *ethhdr = eth_hdr(skb); 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; struct sk_buff *new_skb;
unicast_packet = (struct batadv_unicast_packet *)skb->data; unicast_packet = (struct batadv_unicast_packet *)skb->data;
...@@ -835,6 +835,22 @@ static int batadv_route_unicast_packet(struct sk_buff *skb, ...@@ -835,6 +835,22 @@ static int batadv_route_unicast_packet(struct sk_buff *skb,
/* decrement ttl */ /* decrement ttl */
unicast_packet->header.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); res = batadv_send_skb_to_orig(skb, orig_node, recv_if);
/* translate transmit result into receive result */ /* translate transmit result into receive result */
...@@ -1193,6 +1209,8 @@ int batadv_recv_bcast_packet(struct sk_buff *skb, ...@@ -1193,6 +1209,8 @@ int batadv_recv_bcast_packet(struct sk_buff *skb,
if (batadv_bla_check_bcast_duplist(bat_priv, skb)) if (batadv_bla_check_bcast_duplist(bat_priv, skb))
goto out; goto out;
batadv_skb_set_priority(skb, sizeof(struct batadv_bcast_packet));
/* rebroadcast packet */ /* rebroadcast packet */
batadv_add_bcast_packet_to_list(bat_priv, skb, 1); batadv_add_bcast_packet_to_list(bat_priv, skb, 1);
......
...@@ -67,7 +67,6 @@ int batadv_send_skb_packet(struct sk_buff *skb, ...@@ -67,7 +67,6 @@ int batadv_send_skb_packet(struct sk_buff *skb,
ethhdr->h_proto = __constant_htons(ETH_P_BATMAN); ethhdr->h_proto = __constant_htons(ETH_P_BATMAN);
skb_set_network_header(skb, ETH_HLEN); skb_set_network_header(skb, ETH_HLEN);
skb->priority = TC_PRIO_CONTROL;
skb->protocol = __constant_htons(ETH_P_BATMAN); skb->protocol = __constant_htons(ETH_P_BATMAN);
skb->dev = hard_iface->net_dev; skb->dev = hard_iface->net_dev;
......
...@@ -229,6 +229,8 @@ static int batadv_interface_tx(struct sk_buff *skb, ...@@ -229,6 +229,8 @@ static int batadv_interface_tx(struct sk_buff *skb,
*/ */
} }
batadv_skb_set_priority(skb, 0);
/* ethernet packet should be broadcasted */ /* ethernet packet should be broadcasted */
if (do_bcast) { if (do_bcast) {
primary_if = batadv_primary_if_get_selected(bat_priv); primary_if = batadv_primary_if_get_selected(bat_priv);
......
...@@ -385,6 +385,10 @@ static ssize_t batadv_store_gw_mode(struct kobject *kobj, ...@@ -385,6 +385,10 @@ static ssize_t batadv_store_gw_mode(struct kobject *kobj,
curr_gw_mode_str, buff); curr_gw_mode_str, buff);
batadv_gw_deselect(bat_priv); 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); atomic_set(&bat_priv->gw_mode, (unsigned int)gw_mode_tmp);
return count; return count;
} }
......
...@@ -1626,6 +1626,7 @@ batadv_tt_response_fill_table(uint16_t tt_len, uint8_t ttvn, ...@@ -1626,6 +1626,7 @@ batadv_tt_response_fill_table(uint16_t tt_len, uint8_t ttvn,
if (!skb) if (!skb)
goto out; goto out;
skb->priority = TC_PRIO_CONTROL;
skb_reserve(skb, ETH_HLEN); skb_reserve(skb, ETH_HLEN);
tt_response = (struct batadv_tt_query_packet *)skb_put(skb, len); tt_response = (struct batadv_tt_query_packet *)skb_put(skb, len);
tt_response->ttvn = ttvn; tt_response->ttvn = ttvn;
...@@ -1691,6 +1692,7 @@ static int batadv_send_tt_request(struct batadv_priv *bat_priv, ...@@ -1691,6 +1692,7 @@ static int batadv_send_tt_request(struct batadv_priv *bat_priv,
if (!skb) if (!skb)
goto out; goto out;
skb->priority = TC_PRIO_CONTROL;
skb_reserve(skb, ETH_HLEN); skb_reserve(skb, ETH_HLEN);
tt_req_len = sizeof(*tt_request); tt_req_len = sizeof(*tt_request);
...@@ -1788,6 +1790,7 @@ batadv_send_other_tt_response(struct batadv_priv *bat_priv, ...@@ -1788,6 +1790,7 @@ batadv_send_other_tt_response(struct batadv_priv *bat_priv,
if (!skb) if (!skb)
goto unlock; goto unlock;
skb->priority = TC_PRIO_CONTROL;
skb_reserve(skb, ETH_HLEN); skb_reserve(skb, ETH_HLEN);
packet_pos = skb_put(skb, len); packet_pos = skb_put(skb, len);
tt_response = (struct batadv_tt_query_packet *)packet_pos; tt_response = (struct batadv_tt_query_packet *)packet_pos;
...@@ -1906,6 +1909,7 @@ batadv_send_my_tt_response(struct batadv_priv *bat_priv, ...@@ -1906,6 +1909,7 @@ batadv_send_my_tt_response(struct batadv_priv *bat_priv,
if (!skb) if (!skb)
goto unlock; goto unlock;
skb->priority = TC_PRIO_CONTROL;
skb_reserve(skb, ETH_HLEN); skb_reserve(skb, ETH_HLEN);
packet_pos = skb_put(skb, len); packet_pos = skb_put(skb, len);
tt_response = (struct batadv_tt_query_packet *)packet_pos; tt_response = (struct batadv_tt_query_packet *)packet_pos;
...@@ -2240,6 +2244,7 @@ static void batadv_send_roam_adv(struct batadv_priv *bat_priv, uint8_t *client, ...@@ -2240,6 +2244,7 @@ static void batadv_send_roam_adv(struct batadv_priv *bat_priv, uint8_t *client,
if (!skb) if (!skb)
goto out; goto out;
skb->priority = TC_PRIO_CONTROL;
skb_reserve(skb, ETH_HLEN); skb_reserve(skb, ETH_HLEN);
roam_adv_packet = (struct batadv_roam_adv_packet *)skb_put(skb, len); roam_adv_packet = (struct batadv_roam_adv_packet *)skb_put(skb, len);
......
...@@ -242,6 +242,8 @@ int batadv_frag_send_skb(struct sk_buff *skb, struct batadv_priv *bat_priv, ...@@ -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); frag_skb = dev_alloc_skb(data_len - (data_len / 2) + ucf_hdr_len);
if (!frag_skb) if (!frag_skb)
goto dropped; goto dropped;
skb->priority = TC_PRIO_CONTROL;
skb_reserve(frag_skb, ucf_hdr_len); skb_reserve(frag_skb, ucf_hdr_len);
unicast_packet = (struct batadv_unicast_packet *)skb->data; unicast_packet = (struct batadv_unicast_packet *)skb->data;
......
...@@ -397,6 +397,7 @@ batadv_add_packet(struct batadv_priv *bat_priv, ...@@ -397,6 +397,7 @@ batadv_add_packet(struct batadv_priv *bat_priv,
kfree(info); kfree(info);
return NULL; return NULL;
} }
info->skb_packet->priority = TC_PRIO_CONTROL;
skb_reserve(info->skb_packet, ETH_HLEN); skb_reserve(info->skb_packet, ETH_HLEN);
packet = (struct batadv_vis_packet *)skb_put(info->skb_packet, len); packet = (struct batadv_vis_packet *)skb_put(info->skb_packet, len);
...@@ -861,6 +862,7 @@ int batadv_vis_init(struct batadv_priv *bat_priv) ...@@ -861,6 +862,7 @@ int batadv_vis_init(struct batadv_priv *bat_priv)
if (!bat_priv->vis.my_info->skb_packet) if (!bat_priv->vis.my_info->skb_packet)
goto free_info; 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); skb_reserve(bat_priv->vis.my_info->skb_packet, ETH_HLEN);
tmp_skb = bat_priv->vis.my_info->skb_packet; tmp_skb = bat_priv->vis.my_info->skb_packet;
packet = (struct batadv_vis_packet *)skb_put(tmp_skb, sizeof(*packet)); packet = (struct batadv_vis_packet *)skb_put(tmp_skb, sizeof(*packet));
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment