Commit 16c788de 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:

* fix a little bug in the DHCP packet snooping introduced so far
* minor fixes and cleanups
* minor routing protocol API cleanups
* add a new contributor name to translation-table.{c,h}
* update copyright years in file headers
* minor improvement for the routing algorithm
parents 06a4c1c5 35c133a0
......@@ -83,8 +83,8 @@ int debug_log(struct bat_priv *bat_priv, const char *fmt, ...)
va_start(args, fmt);
vscnprintf(tmp_log_buf, sizeof(tmp_log_buf), fmt, args);
fdebug_log(bat_priv->debug_log, "[%10lu] %s",
(jiffies / HZ), tmp_log_buf);
fdebug_log(bat_priv->debug_log, "[%10u] %s",
jiffies_to_msecs(jiffies), tmp_log_buf);
va_end(args);
return 0;
......
This diff is collapsed.
......@@ -63,7 +63,7 @@ struct bat_attribute bat_attr_##_name = { \
.store = _store, \
};
#define BAT_ATTR_STORE_BOOL(_name, _post_func) \
#define BAT_ATTR_SIF_STORE_BOOL(_name, _post_func) \
ssize_t store_##_name(struct kobject *kobj, struct attribute *attr, \
char *buff, size_t count) \
{ \
......@@ -73,9 +73,9 @@ ssize_t store_##_name(struct kobject *kobj, struct attribute *attr, \
&bat_priv->_name, net_dev); \
}
#define BAT_ATTR_SHOW_BOOL(_name) \
ssize_t show_##_name(struct kobject *kobj, struct attribute *attr, \
char *buff) \
#define BAT_ATTR_SIF_SHOW_BOOL(_name) \
ssize_t show_##_name(struct kobject *kobj, \
struct attribute *attr, char *buff) \
{ \
struct bat_priv *bat_priv = kobj_to_batpriv(kobj); \
return sprintf(buff, "%s\n", \
......@@ -83,16 +83,17 @@ ssize_t show_##_name(struct kobject *kobj, struct attribute *attr, \
"disabled" : "enabled"); \
} \
/* Use this, if you are going to turn a [name] in bat_priv on or off */
#define BAT_ATTR_BOOL(_name, _mode, _post_func) \
static BAT_ATTR_STORE_BOOL(_name, _post_func) \
static BAT_ATTR_SHOW_BOOL(_name) \
/* Use this, if you are going to turn a [name] in the soft-interface
* (bat_priv) on or off */
#define BAT_ATTR_SIF_BOOL(_name, _mode, _post_func) \
static BAT_ATTR_SIF_STORE_BOOL(_name, _post_func) \
static BAT_ATTR_SIF_SHOW_BOOL(_name) \
static BAT_ATTR(_name, _mode, show_##_name, store_##_name)
#define BAT_ATTR_STORE_UINT(_name, _min, _max, _post_func) \
#define BAT_ATTR_SIF_STORE_UINT(_name, _min, _max, _post_func) \
ssize_t store_##_name(struct kobject *kobj, struct attribute *attr, \
char *buff, size_t count) \
char *buff, size_t count) \
{ \
struct net_device *net_dev = kobj_to_netdev(kobj); \
struct bat_priv *bat_priv = netdev_priv(net_dev); \
......@@ -100,19 +101,62 @@ ssize_t store_##_name(struct kobject *kobj, struct attribute *attr, \
attr, &bat_priv->_name, net_dev); \
}
#define BAT_ATTR_SHOW_UINT(_name) \
ssize_t show_##_name(struct kobject *kobj, struct attribute *attr, \
char *buff) \
#define BAT_ATTR_SIF_SHOW_UINT(_name) \
ssize_t show_##_name(struct kobject *kobj, \
struct attribute *attr, char *buff) \
{ \
struct bat_priv *bat_priv = kobj_to_batpriv(kobj); \
return sprintf(buff, "%i\n", atomic_read(&bat_priv->_name)); \
} \
/* Use this, if you are going to set [name] in bat_priv to unsigned integer
* values only */
#define BAT_ATTR_UINT(_name, _mode, _min, _max, _post_func) \
static BAT_ATTR_STORE_UINT(_name, _min, _max, _post_func) \
static BAT_ATTR_SHOW_UINT(_name) \
/* Use this, if you are going to set [name] in the soft-interface
* (bat_priv) to an unsigned integer value */
#define BAT_ATTR_SIF_UINT(_name, _mode, _min, _max, _post_func) \
static BAT_ATTR_SIF_STORE_UINT(_name, _min, _max, _post_func) \
static BAT_ATTR_SIF_SHOW_UINT(_name) \
static BAT_ATTR(_name, _mode, show_##_name, store_##_name)
#define BAT_ATTR_HIF_STORE_UINT(_name, _min, _max, _post_func) \
ssize_t store_##_name(struct kobject *kobj, struct attribute *attr, \
char *buff, size_t count) \
{ \
struct net_device *net_dev = kobj_to_netdev(kobj); \
struct hard_iface *hard_iface = hardif_get_by_netdev(net_dev); \
ssize_t length; \
\
if (!hard_iface) \
return 0; \
\
length = __store_uint_attr(buff, count, _min, _max, _post_func, \
attr, &hard_iface->_name, net_dev); \
\
hardif_free_ref(hard_iface); \
return length; \
}
#define BAT_ATTR_HIF_SHOW_UINT(_name) \
ssize_t show_##_name(struct kobject *kobj, \
struct attribute *attr, char *buff) \
{ \
struct net_device *net_dev = kobj_to_netdev(kobj); \
struct hard_iface *hard_iface = hardif_get_by_netdev(net_dev); \
ssize_t length; \
\
if (!hard_iface) \
return 0; \
\
length = sprintf(buff, "%i\n", atomic_read(&hard_iface->_name));\
\
hardif_free_ref(hard_iface); \
return length; \
}
/* Use this, if you are going to set [name] in hard_iface to an
* unsigned integer value*/
#define BAT_ATTR_HIF_UINT(_name, _mode, _min, _max, _post_func) \
static BAT_ATTR_HIF_STORE_UINT(_name, _min, _max, _post_func) \
static BAT_ATTR_HIF_SHOW_UINT(_name) \
static BAT_ATTR(_name, _mode, show_##_name, store_##_name)
......@@ -384,24 +428,24 @@ static ssize_t store_gw_bwidth(struct kobject *kobj, struct attribute *attr,
return gw_bandwidth_set(net_dev, buff, count);
}
BAT_ATTR_BOOL(aggregated_ogms, S_IRUGO | S_IWUSR, NULL);
BAT_ATTR_BOOL(bonding, S_IRUGO | S_IWUSR, NULL);
BAT_ATTR_SIF_BOOL(aggregated_ogms, S_IRUGO | S_IWUSR, NULL);
BAT_ATTR_SIF_BOOL(bonding, S_IRUGO | S_IWUSR, NULL);
#ifdef CONFIG_BATMAN_ADV_BLA
BAT_ATTR_BOOL(bridge_loop_avoidance, S_IRUGO | S_IWUSR, NULL);
BAT_ATTR_SIF_BOOL(bridge_loop_avoidance, S_IRUGO | S_IWUSR, NULL);
#endif
BAT_ATTR_BOOL(fragmentation, S_IRUGO | S_IWUSR, update_min_mtu);
BAT_ATTR_BOOL(ap_isolation, S_IRUGO | S_IWUSR, NULL);
BAT_ATTR_SIF_BOOL(fragmentation, S_IRUGO | S_IWUSR, update_min_mtu);
BAT_ATTR_SIF_BOOL(ap_isolation, S_IRUGO | S_IWUSR, NULL);
static BAT_ATTR(vis_mode, S_IRUGO | S_IWUSR, show_vis_mode, store_vis_mode);
static BAT_ATTR(routing_algo, S_IRUGO, show_bat_algo, NULL);
static BAT_ATTR(gw_mode, S_IRUGO | S_IWUSR, show_gw_mode, store_gw_mode);
BAT_ATTR_UINT(orig_interval, S_IRUGO | S_IWUSR, 2 * JITTER, INT_MAX, NULL);
BAT_ATTR_UINT(hop_penalty, S_IRUGO | S_IWUSR, 0, TQ_MAX_VALUE, NULL);
BAT_ATTR_UINT(gw_sel_class, S_IRUGO | S_IWUSR, 1, TQ_MAX_VALUE,
post_gw_deselect);
BAT_ATTR_SIF_UINT(orig_interval, S_IRUGO | S_IWUSR, 2 * JITTER, INT_MAX, NULL);
BAT_ATTR_SIF_UINT(hop_penalty, S_IRUGO | S_IWUSR, 0, TQ_MAX_VALUE, NULL);
BAT_ATTR_SIF_UINT(gw_sel_class, S_IRUGO | S_IWUSR, 1, TQ_MAX_VALUE,
post_gw_deselect);
static BAT_ATTR(gw_bandwidth, S_IRUGO | S_IWUSR, show_gw_bwidth,
store_gw_bwidth);
#ifdef CONFIG_BATMAN_ADV_DEBUG
BAT_ATTR_UINT(log_level, S_IRUGO | S_IWUSR, 0, 15, NULL);
BAT_ATTR_SIF_UINT(log_level, S_IRUGO | S_IWUSR, 0, 15, NULL);
#endif
static struct bat_attribute *mesh_attrs[] = {
......
/*
* Copyright (C) 2011 B.A.T.M.A.N. contributors:
* Copyright (C) 2011-2012 B.A.T.M.A.N. contributors:
*
* Simon Wunderlich
*
......
/*
* Copyright (C) 2011 B.A.T.M.A.N. contributors:
* Copyright (C) 2011-2012 B.A.T.M.A.N. contributors:
*
* Simon Wunderlich
*
......
......@@ -558,10 +558,10 @@ static bool is_type_dhcprequest(struct sk_buff *skb, int header_len)
p++;
/* ...and then we jump over the data */
if (pkt_len < *p)
if (pkt_len < 1 + (*p))
goto out;
pkt_len -= *p;
p += (*p);
pkt_len -= 1 + (*p);
p += 1 + (*p);
}
}
out:
......
......@@ -32,12 +32,6 @@
#include <linux/if_arp.h>
static int batman_skb_recv(struct sk_buff *skb,
struct net_device *dev,
struct packet_type *ptype,
struct net_device *orig_dev);
void hardif_free_rcu(struct rcu_head *rcu)
{
struct hard_iface *hard_iface;
......@@ -234,7 +228,7 @@ static void hardif_activate_interface(struct hard_iface *hard_iface)
bat_priv = netdev_priv(hard_iface->soft_iface);
bat_priv->bat_algo_ops->bat_ogm_update_mac(hard_iface);
bat_priv->bat_algo_ops->bat_iface_update_mac(hard_iface);
hard_iface->if_status = IF_TO_BE_ACTIVATED;
/**
......@@ -530,7 +524,7 @@ static int hard_if_event(struct notifier_block *this,
check_known_mac_addr(hard_iface->net_dev);
bat_priv = netdev_priv(hard_iface->soft_iface);
bat_priv->bat_algo_ops->bat_ogm_update_mac(hard_iface);
bat_priv->bat_algo_ops->bat_iface_update_mac(hard_iface);
primary_if = primary_if_get_selected(bat_priv);
if (!primary_if)
......@@ -551,113 +545,6 @@ static int hard_if_event(struct notifier_block *this,
return NOTIFY_DONE;
}
/* incoming packets with the batman ethertype received on any active hard
* interface */
static int batman_skb_recv(struct sk_buff *skb, struct net_device *dev,
struct packet_type *ptype,
struct net_device *orig_dev)
{
struct bat_priv *bat_priv;
struct batman_ogm_packet *batman_ogm_packet;
struct hard_iface *hard_iface;
int ret;
hard_iface = container_of(ptype, struct hard_iface, batman_adv_ptype);
skb = skb_share_check(skb, GFP_ATOMIC);
/* skb was released by skb_share_check() */
if (!skb)
goto err_out;
/* packet should hold at least type and version */
if (unlikely(!pskb_may_pull(skb, 2)))
goto err_free;
/* expect a valid ethernet header here. */
if (unlikely(skb->mac_len != ETH_HLEN || !skb_mac_header(skb)))
goto err_free;
if (!hard_iface->soft_iface)
goto err_free;
bat_priv = netdev_priv(hard_iface->soft_iface);
if (atomic_read(&bat_priv->mesh_state) != MESH_ACTIVE)
goto err_free;
/* discard frames on not active interfaces */
if (hard_iface->if_status != IF_ACTIVE)
goto err_free;
batman_ogm_packet = (struct batman_ogm_packet *)skb->data;
if (batman_ogm_packet->header.version != COMPAT_VERSION) {
bat_dbg(DBG_BATMAN, bat_priv,
"Drop packet: incompatible batman version (%i)\n",
batman_ogm_packet->header.version);
goto err_free;
}
/* all receive handlers return whether they received or reused
* the supplied skb. if not, we have to free the skb. */
switch (batman_ogm_packet->header.packet_type) {
/* batman originator packet */
case BAT_IV_OGM:
ret = recv_bat_ogm_packet(skb, hard_iface);
break;
/* batman icmp packet */
case BAT_ICMP:
ret = recv_icmp_packet(skb, hard_iface);
break;
/* unicast packet */
case BAT_UNICAST:
ret = recv_unicast_packet(skb, hard_iface);
break;
/* fragmented unicast packet */
case BAT_UNICAST_FRAG:
ret = recv_ucast_frag_packet(skb, hard_iface);
break;
/* broadcast packet */
case BAT_BCAST:
ret = recv_bcast_packet(skb, hard_iface);
break;
/* vis packet */
case BAT_VIS:
ret = recv_vis_packet(skb, hard_iface);
break;
/* Translation table query (request or response) */
case BAT_TT_QUERY:
ret = recv_tt_query(skb, hard_iface);
break;
/* Roaming advertisement */
case BAT_ROAM_ADV:
ret = recv_roam_adv(skb, hard_iface);
break;
default:
ret = NET_RX_DROP;
}
if (ret == NET_RX_DROP)
kfree_skb(skb);
/* return NET_RX_SUCCESS in any case as we
* most probably dropped the packet for
* routing-logical reasons. */
return NET_RX_SUCCESS;
err_free:
kfree_skb(skb);
err_out:
return NET_RX_DROP;
}
/* This function returns true if the interface represented by ifindex is a
* 802.11 wireless device */
bool is_wifi_iface(int ifindex)
......
......@@ -39,6 +39,7 @@
/* List manipulations on hardif_list have to be rtnl_lock()'ed,
* list traversals just rcu-locked */
struct list_head hardif_list;
static int (*recv_packet_handler[256])(struct sk_buff *, struct hard_iface *);
char bat_routing_algo[20] = "BATMAN IV";
static struct hlist_head bat_algo_list;
......@@ -46,11 +47,15 @@ unsigned char broadcast_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
struct workqueue_struct *bat_event_workqueue;
static void recv_handler_init(void);
static int __init batman_init(void)
{
INIT_LIST_HEAD(&hardif_list);
INIT_HLIST_HEAD(&bat_algo_list);
recv_handler_init();
bat_iv_init();
/* the name should not be longer than 10 chars - see
......@@ -179,6 +184,120 @@ int is_my_mac(const uint8_t *addr)
return 0;
}
static int recv_unhandled_packet(struct sk_buff *skb,
struct hard_iface *recv_if)
{
return NET_RX_DROP;
}
/* incoming packets with the batman ethertype received on any active hard
* interface
*/
int batman_skb_recv(struct sk_buff *skb, struct net_device *dev,
struct packet_type *ptype, struct net_device *orig_dev)
{
struct bat_priv *bat_priv;
struct batman_ogm_packet *batman_ogm_packet;
struct hard_iface *hard_iface;
uint8_t idx;
int ret;
hard_iface = container_of(ptype, struct hard_iface, batman_adv_ptype);
skb = skb_share_check(skb, GFP_ATOMIC);
/* skb was released by skb_share_check() */
if (!skb)
goto err_out;
/* packet should hold at least type and version */
if (unlikely(!pskb_may_pull(skb, 2)))
goto err_free;
/* expect a valid ethernet header here. */
if (unlikely(skb->mac_len != ETH_HLEN || !skb_mac_header(skb)))
goto err_free;
if (!hard_iface->soft_iface)
goto err_free;
bat_priv = netdev_priv(hard_iface->soft_iface);
if (atomic_read(&bat_priv->mesh_state) != MESH_ACTIVE)
goto err_free;
/* discard frames on not active interfaces */
if (hard_iface->if_status != IF_ACTIVE)
goto err_free;
batman_ogm_packet = (struct batman_ogm_packet *)skb->data;
if (batman_ogm_packet->header.version != COMPAT_VERSION) {
bat_dbg(DBG_BATMAN, bat_priv,
"Drop packet: incompatible batman version (%i)\n",
batman_ogm_packet->header.version);
goto err_free;
}
/* all receive handlers return whether they received or reused
* the supplied skb. if not, we have to free the skb.
*/
idx = batman_ogm_packet->header.packet_type;
ret = (*recv_packet_handler[idx])(skb, hard_iface);
if (ret == NET_RX_DROP)
kfree_skb(skb);
/* return NET_RX_SUCCESS in any case as we
* most probably dropped the packet for
* routing-logical reasons.
*/
return NET_RX_SUCCESS;
err_free:
kfree_skb(skb);
err_out:
return NET_RX_DROP;
}
static void recv_handler_init(void)
{
int i;
for (i = 0; i < ARRAY_SIZE(recv_packet_handler); i++)
recv_packet_handler[i] = recv_unhandled_packet;
/* batman icmp packet */
recv_packet_handler[BAT_ICMP] = recv_icmp_packet;
/* unicast packet */
recv_packet_handler[BAT_UNICAST] = recv_unicast_packet;
/* fragmented unicast packet */
recv_packet_handler[BAT_UNICAST_FRAG] = recv_ucast_frag_packet;
/* broadcast packet */
recv_packet_handler[BAT_BCAST] = recv_bcast_packet;
/* vis packet */
recv_packet_handler[BAT_VIS] = recv_vis_packet;
/* Translation table query (request or response) */
recv_packet_handler[BAT_TT_QUERY] = recv_tt_query;
/* Roaming advertisement */
recv_packet_handler[BAT_ROAM_ADV] = recv_roam_adv;
}
int recv_handler_register(uint8_t packet_type,
int (*recv_handler)(struct sk_buff *,
struct hard_iface *))
{
if (recv_packet_handler[packet_type] != &recv_unhandled_packet)
return -EBUSY;
recv_packet_handler[packet_type] = recv_handler;
return 0;
}
void recv_handler_unregister(uint8_t packet_type)
{
recv_packet_handler[packet_type] = recv_unhandled_packet;
}
static struct bat_algo_ops *bat_algo_get(char *name)
{
struct bat_algo_ops *bat_algo_ops = NULL, *bat_algo_ops_tmp;
......@@ -210,11 +329,10 @@ int bat_algo_register(struct bat_algo_ops *bat_algo_ops)
/* all algorithms must implement all ops (for now) */
if (!bat_algo_ops->bat_iface_enable ||
!bat_algo_ops->bat_iface_disable ||
!bat_algo_ops->bat_iface_update_mac ||
!bat_algo_ops->bat_primary_iface_set ||
!bat_algo_ops->bat_ogm_update_mac ||
!bat_algo_ops->bat_ogm_schedule ||
!bat_algo_ops->bat_ogm_emit ||
!bat_algo_ops->bat_ogm_receive) {
!bat_algo_ops->bat_ogm_emit) {
pr_info("Routing algo '%s' does not implement required ops\n",
bat_algo_ops->name);
goto out;
......
......@@ -155,6 +155,12 @@ void mesh_free(struct net_device *soft_iface);
void inc_module_count(void);
void dec_module_count(void);
int is_my_mac(const uint8_t *addr);
int batman_skb_recv(struct sk_buff *skb, struct net_device *dev,
struct packet_type *ptype, struct net_device *orig_dev);
int recv_handler_register(uint8_t packet_type,
int (*recv_handler)(struct sk_buff *,
struct hard_iface *));
void recv_handler_unregister(uint8_t packet_type);
int bat_algo_register(struct bat_algo_ops *bat_algo_ops);
int bat_algo_select(struct bat_priv *bat_priv, char *name);
int bat_algo_seq_print_text(struct seq_file *seq, void *offset);
......
......@@ -35,7 +35,8 @@ static void purge_orig(struct work_struct *work);
static void start_purge_timer(struct bat_priv *bat_priv)
{
INIT_DELAYED_WORK(&bat_priv->orig_work, purge_orig);
queue_delayed_work(bat_event_workqueue, &bat_priv->orig_work, 1 * HZ);
queue_delayed_work(bat_event_workqueue,
&bat_priv->orig_work, msecs_to_jiffies(1000));
}
/* returns 1 if they are the same originator */
......@@ -84,35 +85,29 @@ struct neigh_node *orig_node_get_router(struct orig_node *orig_node)
return router;
}
struct neigh_node *create_neighbor(struct orig_node *orig_node,
struct orig_node *orig_neigh_node,
const uint8_t *neigh,
struct hard_iface *if_incoming)
struct neigh_node *batadv_neigh_node_new(struct hard_iface *hard_iface,
const uint8_t *neigh_addr,
uint32_t seqno)
{
struct bat_priv *bat_priv = netdev_priv(if_incoming->soft_iface);
struct bat_priv *bat_priv = netdev_priv(hard_iface->soft_iface);
struct neigh_node *neigh_node;
bat_dbg(DBG_BATMAN, bat_priv,
"Creating new last-hop neighbor of originator\n");
neigh_node = kzalloc(sizeof(*neigh_node), GFP_ATOMIC);
if (!neigh_node)
return NULL;
goto out;
INIT_HLIST_NODE(&neigh_node->list);
INIT_LIST_HEAD(&neigh_node->bonding_list);
spin_lock_init(&neigh_node->tq_lock);
memcpy(neigh_node->addr, neigh, ETH_ALEN);
neigh_node->orig_node = orig_neigh_node;
neigh_node->if_incoming = if_incoming;
memcpy(neigh_node->addr, neigh_addr, ETH_ALEN);
/* extra reference for return */
atomic_set(&neigh_node->refcount, 2);
spin_lock_bh(&orig_node->neigh_list_lock);
hlist_add_head_rcu(&neigh_node->list, &orig_node->neigh_list);
spin_unlock_bh(&orig_node->neigh_list_lock);
bat_dbg(DBG_BATMAN, bat_priv,
"Creating new neighbor %pM, initial seqno %d\n",
neigh_addr, seqno);
out:
return neigh_node;
}
......@@ -274,6 +269,7 @@ static bool purge_orig_neighbors(struct bat_priv *bat_priv,
struct hlist_node *node, *node_tmp;
struct neigh_node *neigh_node;
bool neigh_purged = false;
unsigned long last_seen;
*best_neigh_node = NULL;
......@@ -283,11 +279,13 @@ static bool purge_orig_neighbors(struct bat_priv *bat_priv,
hlist_for_each_entry_safe(neigh_node, node, node_tmp,
&orig_node->neigh_list, list) {
if ((has_timed_out(neigh_node->last_valid, PURGE_TIMEOUT)) ||
if ((has_timed_out(neigh_node->last_seen, PURGE_TIMEOUT)) ||
(neigh_node->if_incoming->if_status == IF_INACTIVE) ||
(neigh_node->if_incoming->if_status == IF_NOT_IN_USE) ||
(neigh_node->if_incoming->if_status == IF_TO_BE_REMOVED)) {
last_seen = neigh_node->last_seen;
if ((neigh_node->if_incoming->if_status ==
IF_INACTIVE) ||
(neigh_node->if_incoming->if_status ==
......@@ -300,9 +298,9 @@ static bool purge_orig_neighbors(struct bat_priv *bat_priv,
neigh_node->if_incoming->net_dev->name);
else
bat_dbg(DBG_BATMAN, bat_priv,
"neighbor timeout: originator %pM, neighbor: %pM, last_valid: %lu\n",
"neighbor timeout: originator %pM, neighbor: %pM, last_seen: %u\n",
orig_node->orig, neigh_node->addr,
(neigh_node->last_valid / HZ));
jiffies_to_msecs(last_seen));
neigh_purged = true;
......@@ -325,10 +323,11 @@ static bool purge_orig_node(struct bat_priv *bat_priv,
{
struct neigh_node *best_neigh_node;
if (has_timed_out(orig_node->last_valid, 2 * PURGE_TIMEOUT)) {
if (has_timed_out(orig_node->last_seen, 2 * PURGE_TIMEOUT)) {
bat_dbg(DBG_BATMAN, bat_priv,
"Originator timeout: originator %pM, last_valid %lu\n",
orig_node->orig, (orig_node->last_valid / HZ));
"Originator timeout: originator %pM, last_seen %u\n",
orig_node->orig,
jiffies_to_msecs(orig_node->last_seen));
return true;
} else {
if (purge_orig_neighbors(bat_priv, orig_node,
......@@ -446,9 +445,9 @@ int orig_seq_print_text(struct seq_file *seq, void *offset)
goto next;
last_seen_secs = jiffies_to_msecs(jiffies -
orig_node->last_valid) / 1000;
orig_node->last_seen) / 1000;
last_seen_msecs = jiffies_to_msecs(jiffies -
orig_node->last_valid) % 1000;
orig_node->last_seen) % 1000;
seq_printf(seq, "%pM %4i.%03is (%3i) %pM [%10s]:",
orig_node->orig, last_seen_secs,
......
......@@ -29,10 +29,9 @@ void originator_free(struct bat_priv *bat_priv);
void purge_orig_ref(struct bat_priv *bat_priv);
void orig_node_free_ref(struct orig_node *orig_node);
struct orig_node *get_orig_node(struct bat_priv *bat_priv, const uint8_t *addr);
struct neigh_node *create_neighbor(struct orig_node *orig_node,
struct orig_node *orig_neigh_node,
const uint8_t *neigh,
struct hard_iface *if_incoming);
struct neigh_node *batadv_neigh_node_new(struct hard_iface *hard_iface,
const uint8_t *neigh_addr,
uint32_t seqno);
void neigh_node_free_ref(struct neigh_node *neigh_node);
struct neigh_node *orig_node_get_router(struct orig_node *orig_node);
int orig_seq_print_text(struct seq_file *seq, void *offset);
......
......@@ -39,6 +39,7 @@ enum bat_packettype {
#define COMPAT_VERSION 14
enum batman_iv_flags {
NOT_BEST_NEXT_HOP = 1 << 3,
PRIMARIES_FIRST_HOP = 1 << 4,
VIS_SERVER = 1 << 5,
DIRECTLINK = 1 << 6
......
......@@ -248,37 +248,35 @@ int window_protected(struct bat_priv *bat_priv, int32_t seq_num_diff,
return 0;
}
int recv_bat_ogm_packet(struct sk_buff *skb, struct hard_iface *hard_iface)
bool check_management_packet(struct sk_buff *skb,
struct hard_iface *hard_iface,
int header_len)
{
struct bat_priv *bat_priv = netdev_priv(hard_iface->soft_iface);
struct ethhdr *ethhdr;
/* drop packet if it has not necessary minimum size */
if (unlikely(!pskb_may_pull(skb, BATMAN_OGM_HLEN)))
return NET_RX_DROP;
if (unlikely(!pskb_may_pull(skb, header_len)))
return false;
ethhdr = (struct ethhdr *)skb_mac_header(skb);
/* packet with broadcast indication but unicast recipient */
if (!is_broadcast_ether_addr(ethhdr->h_dest))
return NET_RX_DROP;
return false;
/* packet with broadcast sender address */
if (is_broadcast_ether_addr(ethhdr->h_source))
return NET_RX_DROP;
return false;
/* create a copy of the skb, if needed, to modify it. */
if (skb_cow(skb, 0) < 0)
return NET_RX_DROP;
return false;
/* keep skb linear */
if (skb_linearize(skb) < 0)
return NET_RX_DROP;
bat_priv->bat_algo_ops->bat_ogm_receive(hard_iface, skb);
return false;
kfree_skb(skb);
return NET_RX_SUCCESS;
return true;
}
static int recv_my_icmp_packet(struct bat_priv *bat_priv,
......
......@@ -23,6 +23,9 @@
#define _NET_BATMAN_ADV_ROUTING_H_
void slide_own_bcast_window(struct hard_iface *hard_iface);
bool check_management_packet(struct sk_buff *skb,
struct hard_iface *hard_iface,
int header_len);
void update_route(struct bat_priv *bat_priv, struct orig_node *orig_node,
struct neigh_node *neigh_node);
int recv_icmp_packet(struct sk_buff *skb, struct hard_iface *recv_if);
......@@ -30,7 +33,6 @@ int recv_unicast_packet(struct sk_buff *skb, struct hard_iface *recv_if);
int recv_ucast_frag_packet(struct sk_buff *skb, struct hard_iface *recv_if);
int recv_bcast_packet(struct sk_buff *skb, struct hard_iface *recv_if);
int recv_vis_packet(struct sk_buff *skb, struct hard_iface *recv_if);
int recv_bat_ogm_packet(struct sk_buff *skb, struct hard_iface *recv_if);
int recv_tt_query(struct sk_buff *skb, struct hard_iface *recv_if);
int recv_roam_adv(struct sk_buff *skb, struct hard_iface *recv_if);
struct neigh_node *find_router(struct bat_priv *bat_priv,
......
......@@ -292,7 +292,7 @@ static void send_outstanding_bcast_packet(struct work_struct *work)
/* if we still have some more bcasts to send */
if (forw_packet->num_packets < 3) {
_add_bcast_packet_to_list(bat_priv, forw_packet,
((5 * HZ) / 1000));
msecs_to_jiffies(5));
return;
}
......
/*
* Copyright (C) 2007-2012 B.A.T.M.A.N. contributors:
*
* Marek Lindner, Simon Wunderlich
* Marek Lindner, Simon Wunderlich, Antonio Quartulli
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of version 2 of the GNU General Public
......
/*
* Copyright (C) 2007-2012 B.A.T.M.A.N. contributors:
*
* Marek Lindner, Simon Wunderlich
* Marek Lindner, Simon Wunderlich, Antonio Quartulli
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of version 2 of the GNU General Public
......
......@@ -52,7 +52,7 @@ struct hard_iface {
/**
* orig_node - structure for orig_list maintaining nodes of mesh
* @primary_addr: hosts primary interface address
* @last_valid: when last packet from this node was received
* @last_seen: when last packet from this node was received
* @bcast_seqno_reset: time when the broadcast seqno window was reset
* @batman_seqno_reset: time when the batman seqno window was reset
* @gw_flags: flags related to gateway class
......@@ -70,7 +70,7 @@ struct orig_node {
struct neigh_node __rcu *router; /* rcu protected pointer */
unsigned long *bcast_own;
uint8_t *bcast_own_sum;
unsigned long last_valid;
unsigned long last_seen;
unsigned long bcast_seqno_reset;
unsigned long batman_seqno_reset;
uint8_t gw_flags;
......@@ -120,7 +120,7 @@ struct gw_node {
/**
* neigh_node
* @last_valid: when last packet via this neighbor was received
* @last_seen: when last packet via this neighbor was received
*/
struct neigh_node {
struct hlist_node list;
......@@ -131,7 +131,7 @@ struct neigh_node {
uint8_t tq_avg;
uint8_t last_ttl;
struct list_head bonding_list;
unsigned long last_valid;
unsigned long last_seen;
DECLARE_BITMAP(real_bits, TQ_LOCAL_WINDOW_SIZE);
atomic_t refcount;
struct rcu_head rcu;
......@@ -381,18 +381,17 @@ struct bat_algo_ops {
int (*bat_iface_enable)(struct hard_iface *hard_iface);
/* de-init routing info when hard-interface is disabled */
void (*bat_iface_disable)(struct hard_iface *hard_iface);
/* (re-)init mac addresses of the protocol information
* belonging to this hard-interface
*/
void (*bat_iface_update_mac)(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 */
void (*bat_ogm_update_mac)(struct hard_iface *hard_iface);
/* prepare a new outgoing OGM for the send queue */
void (*bat_ogm_schedule)(struct hard_iface *hard_iface,
int tt_num_changes);
/* send scheduled OGM */
void (*bat_ogm_emit)(struct forw_packet *forw_packet);
/* receive incoming OGM */
void (*bat_ogm_receive)(struct hard_iface *if_incoming,
struct sk_buff *skb);
};
#endif /* _NET_BATMAN_ADV_TYPES_H_ */
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