Merge tag 'batman-adv-for-davem' of git://git.open-mesh.org/linux-merge
Included changes: * remove duplicated line in comment * add htons() invocation for tt_crc as suggested by Al Viro * OriGinator Message seqno initial value is now random * some cleanups and fixes
This commit is contained in:
@@ -30,24 +30,44 @@
|
|||||||
#include "send.h"
|
#include "send.h"
|
||||||
#include "bat_algo.h"
|
#include "bat_algo.h"
|
||||||
|
|
||||||
static void bat_iv_ogm_init(struct hard_iface *hard_iface)
|
static int bat_iv_ogm_iface_enable(struct hard_iface *hard_iface)
|
||||||
{
|
{
|
||||||
struct batman_ogm_packet *batman_ogm_packet;
|
struct batman_ogm_packet *batman_ogm_packet;
|
||||||
|
uint32_t random_seqno;
|
||||||
|
int res = -1;
|
||||||
|
|
||||||
hard_iface->packet_len = BATMAN_OGM_LEN;
|
/* randomize initial seqno to avoid collision */
|
||||||
|
get_random_bytes(&random_seqno, sizeof(random_seqno));
|
||||||
|
atomic_set(&hard_iface->seqno, random_seqno);
|
||||||
|
|
||||||
|
hard_iface->packet_len = BATMAN_OGM_HLEN;
|
||||||
hard_iface->packet_buff = kmalloc(hard_iface->packet_len, GFP_ATOMIC);
|
hard_iface->packet_buff = kmalloc(hard_iface->packet_len, GFP_ATOMIC);
|
||||||
|
|
||||||
|
if (!hard_iface->packet_buff)
|
||||||
|
goto out;
|
||||||
|
|
||||||
batman_ogm_packet = (struct batman_ogm_packet *)hard_iface->packet_buff;
|
batman_ogm_packet = (struct batman_ogm_packet *)hard_iface->packet_buff;
|
||||||
batman_ogm_packet->header.packet_type = BAT_OGM;
|
batman_ogm_packet->header.packet_type = BAT_IV_OGM;
|
||||||
batman_ogm_packet->header.version = COMPAT_VERSION;
|
batman_ogm_packet->header.version = COMPAT_VERSION;
|
||||||
batman_ogm_packet->header.ttl = 2;
|
batman_ogm_packet->header.ttl = 2;
|
||||||
batman_ogm_packet->flags = NO_FLAGS;
|
batman_ogm_packet->flags = NO_FLAGS;
|
||||||
batman_ogm_packet->tq = TQ_MAX_VALUE;
|
batman_ogm_packet->tq = TQ_MAX_VALUE;
|
||||||
batman_ogm_packet->tt_num_changes = 0;
|
batman_ogm_packet->tt_num_changes = 0;
|
||||||
batman_ogm_packet->ttvn = 0;
|
batman_ogm_packet->ttvn = 0;
|
||||||
|
|
||||||
|
res = 0;
|
||||||
|
|
||||||
|
out:
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void bat_iv_ogm_init_primary(struct hard_iface *hard_iface)
|
static void bat_iv_ogm_iface_disable(struct hard_iface *hard_iface)
|
||||||
|
{
|
||||||
|
kfree(hard_iface->packet_buff);
|
||||||
|
hard_iface->packet_buff = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void bat_iv_ogm_primary_iface_set(struct hard_iface *hard_iface)
|
||||||
{
|
{
|
||||||
struct batman_ogm_packet *batman_ogm_packet;
|
struct batman_ogm_packet *batman_ogm_packet;
|
||||||
|
|
||||||
@@ -92,7 +112,7 @@ static uint8_t hop_penalty(uint8_t tq, const struct bat_priv *bat_priv)
|
|||||||
static int bat_iv_ogm_aggr_packet(int buff_pos, int packet_len,
|
static int bat_iv_ogm_aggr_packet(int buff_pos, int packet_len,
|
||||||
int tt_num_changes)
|
int tt_num_changes)
|
||||||
{
|
{
|
||||||
int next_buff_pos = buff_pos + BATMAN_OGM_LEN + tt_len(tt_num_changes);
|
int next_buff_pos = buff_pos + BATMAN_OGM_HLEN + tt_len(tt_num_changes);
|
||||||
|
|
||||||
return (next_buff_pos <= packet_len) &&
|
return (next_buff_pos <= packet_len) &&
|
||||||
(next_buff_pos <= MAX_AGGREGATION_BYTES);
|
(next_buff_pos <= MAX_AGGREGATION_BYTES);
|
||||||
@@ -132,7 +152,7 @@ static void bat_iv_ogm_send_to_if(struct forw_packet *forw_packet,
|
|||||||
"Sending own" :
|
"Sending own" :
|
||||||
"Forwarding"));
|
"Forwarding"));
|
||||||
bat_dbg(DBG_BATMAN, bat_priv,
|
bat_dbg(DBG_BATMAN, bat_priv,
|
||||||
"%s %spacket (originator %pM, seqno %d, TQ %d, TTL %d, IDF %s, ttvn %d) on interface %s [%pM]\n",
|
"%s %spacket (originator %pM, seqno %u, TQ %d, TTL %d, IDF %s, ttvn %d) on interface %s [%pM]\n",
|
||||||
fwd_str, (packet_num > 0 ? "aggregated " : ""),
|
fwd_str, (packet_num > 0 ? "aggregated " : ""),
|
||||||
batman_ogm_packet->orig,
|
batman_ogm_packet->orig,
|
||||||
ntohl(batman_ogm_packet->seqno),
|
ntohl(batman_ogm_packet->seqno),
|
||||||
@@ -142,7 +162,7 @@ static void bat_iv_ogm_send_to_if(struct forw_packet *forw_packet,
|
|||||||
batman_ogm_packet->ttvn, hard_iface->net_dev->name,
|
batman_ogm_packet->ttvn, hard_iface->net_dev->name,
|
||||||
hard_iface->net_dev->dev_addr);
|
hard_iface->net_dev->dev_addr);
|
||||||
|
|
||||||
buff_pos += BATMAN_OGM_LEN +
|
buff_pos += BATMAN_OGM_HLEN +
|
||||||
tt_len(batman_ogm_packet->tt_num_changes);
|
tt_len(batman_ogm_packet->tt_num_changes);
|
||||||
packet_num++;
|
packet_num++;
|
||||||
batman_ogm_packet = (struct batman_ogm_packet *)
|
batman_ogm_packet = (struct batman_ogm_packet *)
|
||||||
@@ -191,7 +211,7 @@ static void bat_iv_ogm_emit(struct forw_packet *forw_packet)
|
|||||||
|
|
||||||
/* FIXME: what about aggregated packets ? */
|
/* FIXME: what about aggregated packets ? */
|
||||||
bat_dbg(DBG_BATMAN, bat_priv,
|
bat_dbg(DBG_BATMAN, bat_priv,
|
||||||
"%s packet (originator %pM, seqno %d, TTL %d) on interface %s [%pM]\n",
|
"%s packet (originator %pM, seqno %u, TTL %d) on interface %s [%pM]\n",
|
||||||
(forw_packet->own ? "Sending own" : "Forwarding"),
|
(forw_packet->own ? "Sending own" : "Forwarding"),
|
||||||
batman_ogm_packet->orig,
|
batman_ogm_packet->orig,
|
||||||
ntohl(batman_ogm_packet->seqno),
|
ntohl(batman_ogm_packet->seqno),
|
||||||
@@ -335,10 +355,9 @@ static void bat_iv_ogm_aggregate_new(const unsigned char *packet_buff,
|
|||||||
if ((atomic_read(&bat_priv->aggregated_ogms)) &&
|
if ((atomic_read(&bat_priv->aggregated_ogms)) &&
|
||||||
(packet_len < MAX_AGGREGATION_BYTES))
|
(packet_len < MAX_AGGREGATION_BYTES))
|
||||||
forw_packet_aggr->skb = dev_alloc_skb(MAX_AGGREGATION_BYTES +
|
forw_packet_aggr->skb = dev_alloc_skb(MAX_AGGREGATION_BYTES +
|
||||||
sizeof(struct ethhdr));
|
ETH_HLEN);
|
||||||
else
|
else
|
||||||
forw_packet_aggr->skb = dev_alloc_skb(packet_len +
|
forw_packet_aggr->skb = dev_alloc_skb(packet_len + ETH_HLEN);
|
||||||
sizeof(struct ethhdr));
|
|
||||||
|
|
||||||
if (!forw_packet_aggr->skb) {
|
if (!forw_packet_aggr->skb) {
|
||||||
if (!own_packet)
|
if (!own_packet)
|
||||||
@@ -346,7 +365,7 @@ static void bat_iv_ogm_aggregate_new(const unsigned char *packet_buff,
|
|||||||
kfree(forw_packet_aggr);
|
kfree(forw_packet_aggr);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
skb_reserve(forw_packet_aggr->skb, sizeof(struct ethhdr));
|
skb_reserve(forw_packet_aggr->skb, ETH_HLEN);
|
||||||
|
|
||||||
INIT_HLIST_NODE(&forw_packet_aggr->list);
|
INIT_HLIST_NODE(&forw_packet_aggr->list);
|
||||||
|
|
||||||
@@ -520,7 +539,7 @@ static void bat_iv_ogm_forward(struct orig_node *orig_node,
|
|||||||
batman_ogm_packet->flags &= ~DIRECTLINK;
|
batman_ogm_packet->flags &= ~DIRECTLINK;
|
||||||
|
|
||||||
bat_iv_ogm_queue_add(bat_priv, (unsigned char *)batman_ogm_packet,
|
bat_iv_ogm_queue_add(bat_priv, (unsigned char *)batman_ogm_packet,
|
||||||
BATMAN_OGM_LEN + tt_len(tt_num_changes),
|
BATMAN_OGM_HLEN + tt_len(tt_num_changes),
|
||||||
if_incoming, 0, bat_iv_ogm_fwd_send_time());
|
if_incoming, 0, bat_iv_ogm_fwd_send_time());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -842,7 +861,8 @@ static int bat_iv_ogm_update_seqnos(const struct ethhdr *ethhdr,
|
|||||||
seq_diff = batman_ogm_packet->seqno - orig_node->last_real_seqno;
|
seq_diff = batman_ogm_packet->seqno - orig_node->last_real_seqno;
|
||||||
|
|
||||||
/* signalize caller that the packet is to be dropped. */
|
/* signalize caller that the packet is to be dropped. */
|
||||||
if (window_protected(bat_priv, seq_diff,
|
if (!hlist_empty(&orig_node->neigh_list) &&
|
||||||
|
window_protected(bat_priv, seq_diff,
|
||||||
&orig_node->batman_seqno_reset))
|
&orig_node->batman_seqno_reset))
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
@@ -873,7 +893,7 @@ static int bat_iv_ogm_update_seqnos(const struct ethhdr *ethhdr,
|
|||||||
|
|
||||||
if (need_update) {
|
if (need_update) {
|
||||||
bat_dbg(DBG_BATMAN, bat_priv,
|
bat_dbg(DBG_BATMAN, bat_priv,
|
||||||
"updating last_seqno: old %d, new %d\n",
|
"updating last_seqno: old %u, new %u\n",
|
||||||
orig_node->last_real_seqno, batman_ogm_packet->seqno);
|
orig_node->last_real_seqno, batman_ogm_packet->seqno);
|
||||||
orig_node->last_real_seqno = batman_ogm_packet->seqno;
|
orig_node->last_real_seqno = batman_ogm_packet->seqno;
|
||||||
}
|
}
|
||||||
@@ -914,7 +934,7 @@ static void bat_iv_ogm_process(const struct ethhdr *ethhdr,
|
|||||||
* packet in an aggregation. Here we expect that the padding
|
* packet in an aggregation. Here we expect that the padding
|
||||||
* is always zero (or not 0x01)
|
* is always zero (or not 0x01)
|
||||||
*/
|
*/
|
||||||
if (batman_ogm_packet->header.packet_type != BAT_OGM)
|
if (batman_ogm_packet->header.packet_type != BAT_IV_OGM)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* could be changed by schedule_own_packet() */
|
/* could be changed by schedule_own_packet() */
|
||||||
@@ -926,7 +946,7 @@ static void bat_iv_ogm_process(const struct ethhdr *ethhdr,
|
|||||||
batman_ogm_packet->orig) ? 1 : 0);
|
batman_ogm_packet->orig) ? 1 : 0);
|
||||||
|
|
||||||
bat_dbg(DBG_BATMAN, bat_priv,
|
bat_dbg(DBG_BATMAN, bat_priv,
|
||||||
"Received BATMAN packet via NB: %pM, IF: %s [%pM] (from OG: %pM, via prev OG: %pM, seqno %d, ttvn %u, crc %u, changes %u, td %d, TTL %d, V %d, IDF %d)\n",
|
"Received BATMAN packet via NB: %pM, IF: %s [%pM] (from OG: %pM, via prev OG: %pM, seqno %u, ttvn %u, crc %u, changes %u, td %d, TTL %d, V %d, IDF %d)\n",
|
||||||
ethhdr->h_source, if_incoming->net_dev->name,
|
ethhdr->h_source, if_incoming->net_dev->name,
|
||||||
if_incoming->net_dev->dev_addr, batman_ogm_packet->orig,
|
if_incoming->net_dev->dev_addr, batman_ogm_packet->orig,
|
||||||
batman_ogm_packet->prev_sender, batman_ogm_packet->seqno,
|
batman_ogm_packet->prev_sender, batman_ogm_packet->seqno,
|
||||||
@@ -1153,12 +1173,12 @@ static void bat_iv_ogm_receive(struct hard_iface *if_incoming,
|
|||||||
batman_ogm_packet->seqno = ntohl(batman_ogm_packet->seqno);
|
batman_ogm_packet->seqno = ntohl(batman_ogm_packet->seqno);
|
||||||
batman_ogm_packet->tt_crc = ntohs(batman_ogm_packet->tt_crc);
|
batman_ogm_packet->tt_crc = ntohs(batman_ogm_packet->tt_crc);
|
||||||
|
|
||||||
tt_buff = packet_buff + buff_pos + BATMAN_OGM_LEN;
|
tt_buff = packet_buff + buff_pos + BATMAN_OGM_HLEN;
|
||||||
|
|
||||||
bat_iv_ogm_process(ethhdr, batman_ogm_packet,
|
bat_iv_ogm_process(ethhdr, batman_ogm_packet,
|
||||||
tt_buff, if_incoming);
|
tt_buff, if_incoming);
|
||||||
|
|
||||||
buff_pos += BATMAN_OGM_LEN +
|
buff_pos += BATMAN_OGM_HLEN +
|
||||||
tt_len(batman_ogm_packet->tt_num_changes);
|
tt_len(batman_ogm_packet->tt_num_changes);
|
||||||
|
|
||||||
batman_ogm_packet = (struct batman_ogm_packet *)
|
batman_ogm_packet = (struct batman_ogm_packet *)
|
||||||
@@ -1169,8 +1189,9 @@ static void bat_iv_ogm_receive(struct hard_iface *if_incoming,
|
|||||||
|
|
||||||
static struct bat_algo_ops batman_iv __read_mostly = {
|
static struct bat_algo_ops batman_iv __read_mostly = {
|
||||||
.name = "BATMAN IV",
|
.name = "BATMAN IV",
|
||||||
.bat_ogm_init = bat_iv_ogm_init,
|
.bat_iface_enable = bat_iv_ogm_iface_enable,
|
||||||
.bat_ogm_init_primary = bat_iv_ogm_init_primary,
|
.bat_iface_disable = bat_iv_ogm_iface_disable,
|
||||||
|
.bat_primary_iface_set = bat_iv_ogm_primary_iface_set,
|
||||||
.bat_ogm_update_mac = bat_iv_ogm_update_mac,
|
.bat_ogm_update_mac = bat_iv_ogm_update_mac,
|
||||||
.bat_ogm_schedule = bat_iv_ogm_schedule,
|
.bat_ogm_schedule = bat_iv_ogm_schedule,
|
||||||
.bat_ogm_emit = bat_iv_ogm_emit,
|
.bat_ogm_emit = bat_iv_ogm_emit,
|
||||||
|
@@ -290,9 +290,7 @@ static void bla_send_claim(struct bat_priv *bat_priv, uint8_t *mac,
|
|||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
ethhdr = (struct ethhdr *)skb->data;
|
ethhdr = (struct ethhdr *)skb->data;
|
||||||
hw_src = (uint8_t *)ethhdr +
|
hw_src = (uint8_t *)ethhdr + ETH_HLEN + sizeof(struct arphdr);
|
||||||
sizeof(struct ethhdr) +
|
|
||||||
sizeof(struct arphdr);
|
|
||||||
|
|
||||||
/* now we pretend that the client would have sent this ... */
|
/* now we pretend that the client would have sent this ... */
|
||||||
switch (claimtype) {
|
switch (claimtype) {
|
||||||
@@ -340,7 +338,7 @@ static void bla_send_claim(struct bat_priv *bat_priv, uint8_t *mac,
|
|||||||
skb_reset_mac_header(skb);
|
skb_reset_mac_header(skb);
|
||||||
skb->protocol = eth_type_trans(skb, soft_iface);
|
skb->protocol = eth_type_trans(skb, soft_iface);
|
||||||
bat_priv->stats.rx_packets++;
|
bat_priv->stats.rx_packets++;
|
||||||
bat_priv->stats.rx_bytes += skb->len + sizeof(struct ethhdr);
|
bat_priv->stats.rx_bytes += skb->len + ETH_HLEN;
|
||||||
soft_iface->last_rx = jiffies;
|
soft_iface->last_rx = jiffies;
|
||||||
|
|
||||||
netif_rx(skb);
|
netif_rx(skb);
|
||||||
@@ -734,7 +732,6 @@ static int handle_claim(struct bat_priv *bat_priv,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @bat_priv: the bat priv with all the soft interface information
|
|
||||||
* @bat_priv: the bat priv with all the soft interface information
|
* @bat_priv: the bat priv with all the soft interface information
|
||||||
* @hw_src: the Hardware source in the ARP Header
|
* @hw_src: the Hardware source in the ARP Header
|
||||||
* @hw_dst: the Hardware destination in the ARP Header
|
* @hw_dst: the Hardware destination in the ARP Header
|
||||||
@@ -845,7 +842,7 @@ static int bla_process_claim(struct bat_priv *bat_priv,
|
|||||||
headlen = sizeof(*vhdr);
|
headlen = sizeof(*vhdr);
|
||||||
} else {
|
} else {
|
||||||
proto = ntohs(ethhdr->h_proto);
|
proto = ntohs(ethhdr->h_proto);
|
||||||
headlen = sizeof(*ethhdr);
|
headlen = ETH_HLEN;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (proto != ETH_P_ARP)
|
if (proto != ETH_P_ARP)
|
||||||
@@ -1303,7 +1300,7 @@ int bla_is_backbone_gw(struct sk_buff *skb,
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* first, find out the vid. */
|
/* first, find out the vid. */
|
||||||
if (!pskb_may_pull(skb, hdr_size + sizeof(struct ethhdr)))
|
if (!pskb_may_pull(skb, hdr_size + ETH_HLEN))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
ethhdr = (struct ethhdr *)(((uint8_t *)skb->data) + hdr_size);
|
ethhdr = (struct ethhdr *)(((uint8_t *)skb->data) + hdr_size);
|
||||||
|
@@ -146,7 +146,7 @@ static void primary_if_select(struct bat_priv *bat_priv,
|
|||||||
if (!new_hard_iface)
|
if (!new_hard_iface)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
bat_priv->bat_algo_ops->bat_ogm_init_primary(new_hard_iface);
|
bat_priv->bat_algo_ops->bat_primary_iface_set(new_hard_iface);
|
||||||
primary_if_update_addr(bat_priv, curr_hard_iface);
|
primary_if_update_addr(bat_priv, curr_hard_iface);
|
||||||
|
|
||||||
out:
|
out:
|
||||||
@@ -304,22 +304,17 @@ int hardif_enable_interface(struct hard_iface *hard_iface,
|
|||||||
if (!softif_is_valid(soft_iface)) {
|
if (!softif_is_valid(soft_iface)) {
|
||||||
pr_err("Can't create batman mesh interface %s: already exists as regular interface\n",
|
pr_err("Can't create batman mesh interface %s: already exists as regular interface\n",
|
||||||
soft_iface->name);
|
soft_iface->name);
|
||||||
dev_put(soft_iface);
|
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
goto err;
|
goto err_dev;
|
||||||
}
|
}
|
||||||
|
|
||||||
hard_iface->soft_iface = soft_iface;
|
hard_iface->soft_iface = soft_iface;
|
||||||
bat_priv = netdev_priv(hard_iface->soft_iface);
|
bat_priv = netdev_priv(hard_iface->soft_iface);
|
||||||
|
|
||||||
bat_priv->bat_algo_ops->bat_ogm_init(hard_iface);
|
ret = bat_priv->bat_algo_ops->bat_iface_enable(hard_iface);
|
||||||
|
if (ret < 0) {
|
||||||
if (!hard_iface->packet_buff) {
|
|
||||||
bat_err(hard_iface->soft_iface,
|
|
||||||
"Can't add interface packet (%s): out of memory\n",
|
|
||||||
hard_iface->net_dev->name);
|
|
||||||
ret = -ENOMEM;
|
ret = -ENOMEM;
|
||||||
goto err;
|
goto err_dev;
|
||||||
}
|
}
|
||||||
|
|
||||||
hard_iface->if_num = bat_priv->num_ifaces;
|
hard_iface->if_num = bat_priv->num_ifaces;
|
||||||
@@ -332,7 +327,6 @@ int hardif_enable_interface(struct hard_iface *hard_iface,
|
|||||||
hard_iface->batman_adv_ptype.dev = hard_iface->net_dev;
|
hard_iface->batman_adv_ptype.dev = hard_iface->net_dev;
|
||||||
dev_add_pack(&hard_iface->batman_adv_ptype);
|
dev_add_pack(&hard_iface->batman_adv_ptype);
|
||||||
|
|
||||||
atomic_set(&hard_iface->seqno, 1);
|
|
||||||
atomic_set(&hard_iface->frag_seqno, 1);
|
atomic_set(&hard_iface->frag_seqno, 1);
|
||||||
bat_info(hard_iface->soft_iface, "Adding interface: %s\n",
|
bat_info(hard_iface->soft_iface, "Adding interface: %s\n",
|
||||||
hard_iface->net_dev->name);
|
hard_iface->net_dev->name);
|
||||||
@@ -364,6 +358,8 @@ int hardif_enable_interface(struct hard_iface *hard_iface,
|
|||||||
out:
|
out:
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
err_dev:
|
||||||
|
dev_put(soft_iface);
|
||||||
err:
|
err:
|
||||||
hardif_free_ref(hard_iface);
|
hardif_free_ref(hard_iface);
|
||||||
return ret;
|
return ret;
|
||||||
@@ -398,8 +394,7 @@ void hardif_disable_interface(struct hard_iface *hard_iface)
|
|||||||
hardif_free_ref(new_if);
|
hardif_free_ref(new_if);
|
||||||
}
|
}
|
||||||
|
|
||||||
kfree(hard_iface->packet_buff);
|
bat_priv->bat_algo_ops->bat_iface_disable(hard_iface);
|
||||||
hard_iface->packet_buff = NULL;
|
|
||||||
hard_iface->if_status = IF_NOT_IN_USE;
|
hard_iface->if_status = IF_NOT_IN_USE;
|
||||||
|
|
||||||
/* delete all references to this hard_iface */
|
/* delete all references to this hard_iface */
|
||||||
@@ -451,6 +446,13 @@ static struct hard_iface *hardif_add_interface(struct net_device *net_dev)
|
|||||||
check_known_mac_addr(hard_iface->net_dev);
|
check_known_mac_addr(hard_iface->net_dev);
|
||||||
list_add_tail_rcu(&hard_iface->list, &hardif_list);
|
list_add_tail_rcu(&hard_iface->list, &hardif_list);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This can't be called via a bat_priv callback because
|
||||||
|
* we have no bat_priv yet.
|
||||||
|
*/
|
||||||
|
atomic_set(&hard_iface->seqno, 1);
|
||||||
|
hard_iface->packet_buff = NULL;
|
||||||
|
|
||||||
return hard_iface;
|
return hard_iface;
|
||||||
|
|
||||||
free_if:
|
free_if:
|
||||||
@@ -572,8 +574,7 @@ static int batman_skb_recv(struct sk_buff *skb, struct net_device *dev,
|
|||||||
goto err_free;
|
goto err_free;
|
||||||
|
|
||||||
/* expect a valid ethernet header here. */
|
/* expect a valid ethernet header here. */
|
||||||
if (unlikely(skb->mac_len != sizeof(struct ethhdr) ||
|
if (unlikely(skb->mac_len != ETH_HLEN || !skb_mac_header(skb)))
|
||||||
!skb_mac_header(skb)))
|
|
||||||
goto err_free;
|
goto err_free;
|
||||||
|
|
||||||
if (!hard_iface->soft_iface)
|
if (!hard_iface->soft_iface)
|
||||||
@@ -602,7 +603,7 @@ static int batman_skb_recv(struct sk_buff *skb, struct net_device *dev,
|
|||||||
|
|
||||||
switch (batman_ogm_packet->header.packet_type) {
|
switch (batman_ogm_packet->header.packet_type) {
|
||||||
/* batman originator packet */
|
/* batman originator packet */
|
||||||
case BAT_OGM:
|
case BAT_IV_OGM:
|
||||||
ret = recv_bat_ogm_packet(skb, hard_iface);
|
ret = recv_bat_ogm_packet(skb, hard_iface);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@@ -175,13 +175,13 @@ static ssize_t bat_socket_write(struct file *file, const char __user *buff,
|
|||||||
if (len >= sizeof(struct icmp_packet_rr))
|
if (len >= sizeof(struct icmp_packet_rr))
|
||||||
packet_len = sizeof(struct icmp_packet_rr);
|
packet_len = sizeof(struct icmp_packet_rr);
|
||||||
|
|
||||||
skb = dev_alloc_skb(packet_len + sizeof(struct ethhdr));
|
skb = dev_alloc_skb(packet_len + ETH_HLEN);
|
||||||
if (!skb) {
|
if (!skb) {
|
||||||
len = -ENOMEM;
|
len = -ENOMEM;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
skb_reserve(skb, sizeof(struct ethhdr));
|
skb_reserve(skb, ETH_HLEN);
|
||||||
icmp_packet = (struct icmp_packet_rr *)skb_put(skb, packet_len);
|
icmp_packet = (struct icmp_packet_rr *)skb_put(skb, packet_len);
|
||||||
|
|
||||||
if (copy_from_user(icmp_packet, buff, packet_len)) {
|
if (copy_from_user(icmp_packet, buff, packet_len)) {
|
||||||
|
@@ -208,8 +208,9 @@ int bat_algo_register(struct bat_algo_ops *bat_algo_ops)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* all algorithms must implement all ops (for now) */
|
/* all algorithms must implement all ops (for now) */
|
||||||
if (!bat_algo_ops->bat_ogm_init ||
|
if (!bat_algo_ops->bat_iface_enable ||
|
||||||
!bat_algo_ops->bat_ogm_init_primary ||
|
!bat_algo_ops->bat_iface_disable ||
|
||||||
|
!bat_algo_ops->bat_primary_iface_set ||
|
||||||
!bat_algo_ops->bat_ogm_update_mac ||
|
!bat_algo_ops->bat_ogm_update_mac ||
|
||||||
!bat_algo_ops->bat_ogm_schedule ||
|
!bat_algo_ops->bat_ogm_schedule ||
|
||||||
!bat_algo_ops->bat_ogm_emit ||
|
!bat_algo_ops->bat_ogm_emit ||
|
||||||
|
@@ -25,7 +25,7 @@
|
|||||||
#define ETH_P_BATMAN 0x4305 /* unofficial/not registered Ethertype */
|
#define ETH_P_BATMAN 0x4305 /* unofficial/not registered Ethertype */
|
||||||
|
|
||||||
enum bat_packettype {
|
enum bat_packettype {
|
||||||
BAT_OGM = 0x01,
|
BAT_IV_OGM = 0x01,
|
||||||
BAT_ICMP = 0x02,
|
BAT_ICMP = 0x02,
|
||||||
BAT_UNICAST = 0x03,
|
BAT_UNICAST = 0x03,
|
||||||
BAT_BCAST = 0x04,
|
BAT_BCAST = 0x04,
|
||||||
@@ -38,7 +38,7 @@ enum bat_packettype {
|
|||||||
/* this file is included by batctl which needs these defines */
|
/* this file is included by batctl which needs these defines */
|
||||||
#define COMPAT_VERSION 14
|
#define COMPAT_VERSION 14
|
||||||
|
|
||||||
enum batman_flags {
|
enum batman_iv_flags {
|
||||||
PRIMARIES_FIRST_HOP = 1 << 4,
|
PRIMARIES_FIRST_HOP = 1 << 4,
|
||||||
VIS_SERVER = 1 << 5,
|
VIS_SERVER = 1 << 5,
|
||||||
DIRECTLINK = 1 << 6
|
DIRECTLINK = 1 << 6
|
||||||
@@ -126,7 +126,7 @@ struct batman_ogm_packet {
|
|||||||
uint16_t tt_crc;
|
uint16_t tt_crc;
|
||||||
} __packed;
|
} __packed;
|
||||||
|
|
||||||
#define BATMAN_OGM_LEN sizeof(struct batman_ogm_packet)
|
#define BATMAN_OGM_HLEN sizeof(struct batman_ogm_packet)
|
||||||
|
|
||||||
struct icmp_packet {
|
struct icmp_packet {
|
||||||
struct batman_header header;
|
struct batman_header header;
|
||||||
|
@@ -254,7 +254,7 @@ int recv_bat_ogm_packet(struct sk_buff *skb, struct hard_iface *hard_iface)
|
|||||||
struct ethhdr *ethhdr;
|
struct ethhdr *ethhdr;
|
||||||
|
|
||||||
/* drop packet if it has not necessary minimum size */
|
/* drop packet if it has not necessary minimum size */
|
||||||
if (unlikely(!pskb_may_pull(skb, BATMAN_OGM_LEN)))
|
if (unlikely(!pskb_may_pull(skb, BATMAN_OGM_HLEN)))
|
||||||
return NET_RX_DROP;
|
return NET_RX_DROP;
|
||||||
|
|
||||||
ethhdr = (struct ethhdr *)skb_mac_header(skb);
|
ethhdr = (struct ethhdr *)skb_mac_header(skb);
|
||||||
@@ -313,7 +313,7 @@ static int recv_my_icmp_packet(struct bat_priv *bat_priv,
|
|||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
/* create a copy of the skb, if needed, to modify it. */
|
/* create a copy of the skb, if needed, to modify it. */
|
||||||
if (skb_cow(skb, sizeof(struct ethhdr)) < 0)
|
if (skb_cow(skb, ETH_HLEN) < 0)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
icmp_packet = (struct icmp_packet_rr *)skb->data;
|
icmp_packet = (struct icmp_packet_rr *)skb->data;
|
||||||
@@ -368,7 +368,7 @@ static int recv_icmp_ttl_exceeded(struct bat_priv *bat_priv,
|
|||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
/* create a copy of the skb, if needed, to modify it. */
|
/* create a copy of the skb, if needed, to modify it. */
|
||||||
if (skb_cow(skb, sizeof(struct ethhdr)) < 0)
|
if (skb_cow(skb, ETH_HLEN) < 0)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
icmp_packet = (struct icmp_packet *)skb->data;
|
icmp_packet = (struct icmp_packet *)skb->data;
|
||||||
@@ -454,7 +454,7 @@ int recv_icmp_packet(struct sk_buff *skb, struct hard_iface *recv_if)
|
|||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
/* create a copy of the skb, if needed, to modify it. */
|
/* create a copy of the skb, if needed, to modify it. */
|
||||||
if (skb_cow(skb, sizeof(struct ethhdr)) < 0)
|
if (skb_cow(skb, ETH_HLEN) < 0)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
icmp_packet = (struct icmp_packet_rr *)skb->data;
|
icmp_packet = (struct icmp_packet_rr *)skb->data;
|
||||||
@@ -841,7 +841,7 @@ static int route_unicast_packet(struct sk_buff *skb, struct hard_iface *recv_if)
|
|||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
/* create a copy of the skb, if needed, to modify it. */
|
/* create a copy of the skb, if needed, to modify it. */
|
||||||
if (skb_cow(skb, sizeof(struct ethhdr)) < 0)
|
if (skb_cow(skb, ETH_HLEN) < 0)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
unicast_packet = (struct unicast_packet *)skb->data;
|
unicast_packet = (struct unicast_packet *)skb->data;
|
||||||
|
@@ -51,7 +51,7 @@ int send_skb_packet(struct sk_buff *skb, struct hard_iface *hard_iface,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* push to the ethernet header. */
|
/* push to the ethernet header. */
|
||||||
if (my_skb_head_push(skb, sizeof(*ethhdr)) < 0)
|
if (my_skb_head_push(skb, ETH_HLEN) < 0)
|
||||||
goto send_skb_err;
|
goto send_skb_err;
|
||||||
|
|
||||||
skb_reset_mac_header(skb);
|
skb_reset_mac_header(skb);
|
||||||
@@ -87,7 +87,7 @@ static void realloc_packet_buffer(struct hard_iface *hard_iface,
|
|||||||
/* keep old buffer if kmalloc should fail */
|
/* keep old buffer if kmalloc should fail */
|
||||||
if (new_buff) {
|
if (new_buff) {
|
||||||
memcpy(new_buff, hard_iface->packet_buff,
|
memcpy(new_buff, hard_iface->packet_buff,
|
||||||
BATMAN_OGM_LEN);
|
BATMAN_OGM_HLEN);
|
||||||
|
|
||||||
kfree(hard_iface->packet_buff);
|
kfree(hard_iface->packet_buff);
|
||||||
hard_iface->packet_buff = new_buff;
|
hard_iface->packet_buff = new_buff;
|
||||||
@@ -101,13 +101,13 @@ static int prepare_packet_buffer(struct bat_priv *bat_priv,
|
|||||||
{
|
{
|
||||||
int new_len;
|
int new_len;
|
||||||
|
|
||||||
new_len = BATMAN_OGM_LEN +
|
new_len = BATMAN_OGM_HLEN +
|
||||||
tt_len((uint8_t)atomic_read(&bat_priv->tt_local_changes));
|
tt_len((uint8_t)atomic_read(&bat_priv->tt_local_changes));
|
||||||
|
|
||||||
/* if we have too many changes for one packet don't send any
|
/* if we have too many changes for one packet don't send any
|
||||||
* and wait for the tt table request which will be fragmented */
|
* and wait for the tt table request which will be fragmented */
|
||||||
if (new_len > hard_iface->soft_iface->mtu)
|
if (new_len > hard_iface->soft_iface->mtu)
|
||||||
new_len = BATMAN_OGM_LEN;
|
new_len = BATMAN_OGM_HLEN;
|
||||||
|
|
||||||
realloc_packet_buffer(hard_iface, new_len);
|
realloc_packet_buffer(hard_iface, new_len);
|
||||||
|
|
||||||
@@ -117,14 +117,14 @@ static int prepare_packet_buffer(struct bat_priv *bat_priv,
|
|||||||
atomic_set(&bat_priv->tt_ogm_append_cnt, TT_OGM_APPEND_MAX);
|
atomic_set(&bat_priv->tt_ogm_append_cnt, TT_OGM_APPEND_MAX);
|
||||||
|
|
||||||
return tt_changes_fill_buffer(bat_priv,
|
return tt_changes_fill_buffer(bat_priv,
|
||||||
hard_iface->packet_buff + BATMAN_OGM_LEN,
|
hard_iface->packet_buff + BATMAN_OGM_HLEN,
|
||||||
hard_iface->packet_len - BATMAN_OGM_LEN);
|
hard_iface->packet_len - BATMAN_OGM_HLEN);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int reset_packet_buffer(struct bat_priv *bat_priv,
|
static int reset_packet_buffer(struct bat_priv *bat_priv,
|
||||||
struct hard_iface *hard_iface)
|
struct hard_iface *hard_iface)
|
||||||
{
|
{
|
||||||
realloc_packet_buffer(hard_iface, BATMAN_OGM_LEN);
|
realloc_packet_buffer(hard_iface, BATMAN_OGM_HLEN);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -292,7 +292,7 @@ void interface_rx(struct net_device *soft_iface,
|
|||||||
/* skb->ip_summed = CHECKSUM_UNNECESSARY;*/
|
/* skb->ip_summed = CHECKSUM_UNNECESSARY;*/
|
||||||
|
|
||||||
bat_priv->stats.rx_packets++;
|
bat_priv->stats.rx_packets++;
|
||||||
bat_priv->stats.rx_bytes += skb->len + sizeof(struct ethhdr);
|
bat_priv->stats.rx_bytes += skb->len + ETH_HLEN;
|
||||||
|
|
||||||
soft_iface->last_rx = jiffies;
|
soft_iface->last_rx = jiffies;
|
||||||
|
|
||||||
|
@@ -1339,7 +1339,7 @@ static int send_tt_request(struct bat_priv *bat_priv,
|
|||||||
memcpy(tt_request->dst, dst_orig_node->orig, ETH_ALEN);
|
memcpy(tt_request->dst, dst_orig_node->orig, ETH_ALEN);
|
||||||
tt_request->header.ttl = TTL;
|
tt_request->header.ttl = TTL;
|
||||||
tt_request->ttvn = ttvn;
|
tt_request->ttvn = ttvn;
|
||||||
tt_request->tt_data = tt_crc;
|
tt_request->tt_data = htons(tt_crc);
|
||||||
tt_request->flags = TT_REQUEST;
|
tt_request->flags = TT_REQUEST;
|
||||||
|
|
||||||
if (full_table)
|
if (full_table)
|
||||||
|
@@ -27,7 +27,7 @@
|
|||||||
#include "packet.h"
|
#include "packet.h"
|
||||||
#include "bitarray.h"
|
#include "bitarray.h"
|
||||||
|
|
||||||
#define BAT_HEADER_LEN (sizeof(struct ethhdr) + \
|
#define BAT_HEADER_LEN (ETH_HLEN + \
|
||||||
((sizeof(struct unicast_packet) > sizeof(struct bcast_packet) ? \
|
((sizeof(struct unicast_packet) > sizeof(struct bcast_packet) ? \
|
||||||
sizeof(struct unicast_packet) : \
|
sizeof(struct unicast_packet) : \
|
||||||
sizeof(struct bcast_packet))))
|
sizeof(struct bcast_packet))))
|
||||||
@@ -377,10 +377,12 @@ struct recvlist_node {
|
|||||||
struct bat_algo_ops {
|
struct bat_algo_ops {
|
||||||
struct hlist_node list;
|
struct hlist_node list;
|
||||||
char *name;
|
char *name;
|
||||||
/* init OGM when hard-interface is enabled */
|
/* init routing info when hard-interface is enabled */
|
||||||
void (*bat_ogm_init)(struct hard_iface *hard_iface);
|
int (*bat_iface_enable)(struct hard_iface *hard_iface);
|
||||||
/* init primary OGM when primary interface is selected */
|
/* de-init routing info when hard-interface is disabled */
|
||||||
void (*bat_ogm_init_primary)(struct hard_iface *hard_iface);
|
void (*bat_iface_disable)(struct hard_iface *hard_iface);
|
||||||
|
/* called when primary interface is selected / changed */
|
||||||
|
void (*bat_primary_iface_set)(struct hard_iface *hard_iface);
|
||||||
/* init mac addresses of the OGM belonging to this hard-interface */
|
/* init mac addresses of the OGM belonging to this hard-interface */
|
||||||
void (*bat_ogm_update_mac)(struct hard_iface *hard_iface);
|
void (*bat_ogm_update_mac)(struct hard_iface *hard_iface);
|
||||||
/* prepare a new outgoing OGM for the send queue */
|
/* prepare a new outgoing OGM for the send queue */
|
||||||
|
@@ -434,12 +434,12 @@ static struct vis_info *add_packet(struct bat_priv *bat_priv,
|
|||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
info->skb_packet = dev_alloc_skb(sizeof(*packet) + vis_info_len +
|
info->skb_packet = dev_alloc_skb(sizeof(*packet) + vis_info_len +
|
||||||
sizeof(struct ethhdr));
|
ETH_HLEN);
|
||||||
if (!info->skb_packet) {
|
if (!info->skb_packet) {
|
||||||
kfree(info);
|
kfree(info);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
skb_reserve(info->skb_packet, sizeof(struct ethhdr));
|
skb_reserve(info->skb_packet, ETH_HLEN);
|
||||||
packet = (struct vis_packet *)skb_put(info->skb_packet, sizeof(*packet)
|
packet = (struct vis_packet *)skb_put(info->skb_packet, sizeof(*packet)
|
||||||
+ vis_info_len);
|
+ vis_info_len);
|
||||||
|
|
||||||
@@ -894,11 +894,11 @@ int vis_init(struct bat_priv *bat_priv)
|
|||||||
|
|
||||||
bat_priv->my_vis_info->skb_packet = dev_alloc_skb(sizeof(*packet) +
|
bat_priv->my_vis_info->skb_packet = dev_alloc_skb(sizeof(*packet) +
|
||||||
MAX_VIS_PACKET_SIZE +
|
MAX_VIS_PACKET_SIZE +
|
||||||
sizeof(struct ethhdr));
|
ETH_HLEN);
|
||||||
if (!bat_priv->my_vis_info->skb_packet)
|
if (!bat_priv->my_vis_info->skb_packet)
|
||||||
goto free_info;
|
goto free_info;
|
||||||
|
|
||||||
skb_reserve(bat_priv->my_vis_info->skb_packet, sizeof(struct ethhdr));
|
skb_reserve(bat_priv->my_vis_info->skb_packet, ETH_HLEN);
|
||||||
packet = (struct vis_packet *)skb_put(bat_priv->my_vis_info->skb_packet,
|
packet = (struct vis_packet *)skb_put(bat_priv->my_vis_info->skb_packet,
|
||||||
sizeof(*packet));
|
sizeof(*packet));
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user