Signed-off-by: Marek Lindner lindner_marek@yahoo.de --- bat_iv_ogm.c | 16 +++++++++------- 1 files changed, 9 insertions(+), 7 deletions(-)
diff --git a/bat_iv_ogm.c b/bat_iv_ogm.c index d9195b3..aba0204 100644 --- a/bat_iv_ogm.c +++ b/bat_iv_ogm.c @@ -483,7 +483,8 @@ static void bat_iv_ogm_queue_add(struct bat_priv *bat_priv, static void bat_iv_ogm_forward(struct orig_node *orig_node, const struct ethhdr *ethhdr, struct batman_ogm_packet *batman_ogm_packet, - int directlink, struct hard_iface *if_incoming) + bool is_single_hop_neigh, + struct hard_iface *if_incoming) { struct bat_priv *bat_priv = netdev_priv(if_incoming->soft_iface); struct neigh_node *router; @@ -537,7 +538,7 @@ static void bat_iv_ogm_forward(struct orig_node *orig_node,
/* switch of primaries first hop flag when forwarding */ batman_ogm_packet->flags &= ~PRIMARIES_FIRST_HOP; - if (directlink) + if (is_single_hop_neigh) batman_ogm_packet->flags |= DIRECTLINK; else batman_ogm_packet->flags &= ~DIRECTLINK; @@ -926,7 +927,8 @@ static void bat_iv_ogm_process(const struct ethhdr *ethhdr, struct neigh_node *orig_neigh_router = NULL; int has_directlink_flag; int is_my_addr = 0, is_my_orig = 0, is_my_oldorig = 0; - int is_broadcast = 0, is_bidirectional, is_single_hop_neigh; + int is_broadcast = 0, is_bidirectional; + bool is_single_hop_neigh = false; int is_duplicate; uint32_t if_incoming_seqno;
@@ -950,8 +952,8 @@ static void bat_iv_ogm_process(const struct ethhdr *ethhdr,
has_directlink_flag = (batman_ogm_packet->flags & DIRECTLINK ? 1 : 0);
- is_single_hop_neigh = (compare_eth(ethhdr->h_source, - batman_ogm_packet->orig) ? 1 : 0); + if (compare_eth(ethhdr->h_source, batman_ogm_packet->orig)) + is_single_hop_neigh = true;
bat_dbg(DBG_BATMAN, bat_priv, "Received BATMAN packet via NB: %pM, IF: %s [%pM] " @@ -1125,7 +1127,7 @@ static void bat_iv_ogm_process(const struct ethhdr *ethhdr,
/* mark direct link on incoming interface */ bat_iv_ogm_forward(orig_node, ethhdr, batman_ogm_packet, - 1, if_incoming); + is_single_hop_neigh, if_incoming);
bat_dbg(DBG_BATMAN, bat_priv, "Forwarding packet: " "rebroadcast neighbor packet with direct link flag\n"); @@ -1148,7 +1150,7 @@ static void bat_iv_ogm_process(const struct ethhdr *ethhdr, bat_dbg(DBG_BATMAN, bat_priv, "Forwarding packet: rebroadcast originator packet\n"); bat_iv_ogm_forward(orig_node, ethhdr, batman_ogm_packet, - 0, if_incoming); + is_single_hop_neigh, if_incoming);
out_neigh: if ((orig_neigh_node) && (!is_single_hop_neigh))
The packet handler array replaces the growing switch statement, thus dealing with incoming packets in a more efficient way. It also adds to possibility to register packet handlers on the fly.
Signed-off-by: Marek Lindner lindner_marek@yahoo.de --- hard-interface.c | 114 ---------------------------------------------------- main.c | 118 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ main.h | 6 +++ 3 files changed, 124 insertions(+), 114 deletions(-)
diff --git a/hard-interface.c b/hard-interface.c index cf43540..3ddd5de 100644 --- a/hard-interface.c +++ b/hard-interface.c @@ -33,12 +33,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; @@ -567,114 +561,6 @@ out: 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: - case BAT_UNICAST_4ADDR: - 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) diff --git a/main.c b/main.c index 87b75a9..0d0cd48 100644 --- a/main.c +++ b/main.c @@ -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,119 @@ 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 originator packet */ + recv_packet_handler[BAT_IV_OGM] = recv_bat_ogm_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; diff --git a/main.h b/main.h index 218be63..c25ad17 100644 --- a/main.h +++ b/main.h @@ -178,6 +178,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);
On Thursday 01 March 2012 15:35:17 Marek Lindner wrote:
The packet handler array replaces the growing switch statement,
thus dealing with incoming packets in a more efficient way.
Usually (there are corner cases) the compiler tries to build such kind of jump table from a large switch block. So be careful with this statement.
It also adds to possibility to register packet handlers on the fly.
This is true.
Only scrolled over the patch and it looks like the thing we discussed :)
Kind regards, Sven
On Thursday, March 01, 2012 15:35:17 Marek Lindner wrote:
The packet handler array replaces the growing switch statement, thus dealing with incoming packets in a more efficient way. It also adds to possibility to register packet handlers on the fly.
Applied in revision 1887248.
Regards, Marek
The B.A.T.M.A.N. IV OGM receive function still was hard-coded although it is a routing protocol specific function. This patch takes advantage of the dynamic packet handler registration to remove the hard-coded function calls.
Signed-off-by: Marek Lindner lindner_marek@yahoo.de --- bat_iv_ogm.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++---- main.c | 5 +---- routing.c | 33 --------------------------------- routing.h | 1 - types.h | 3 --- 5 files changed, 53 insertions(+), 45 deletions(-)
diff --git a/bat_iv_ogm.c b/bat_iv_ogm.c index aba0204..5833a3e 100644 --- a/bat_iv_ogm.c +++ b/bat_iv_ogm.c @@ -1166,8 +1166,8 @@ out: orig_node_free_ref(orig_node); }
-static void bat_iv_ogm_receive(struct hard_iface *if_incoming, - struct sk_buff *skb) +static void _bat_iv_ogm_receive(struct sk_buff *skb, + struct hard_iface *if_incoming) { struct batman_ogm_packet *batman_ogm_packet; struct ethhdr *ethhdr; @@ -1200,6 +1200,39 @@ static void bat_iv_ogm_receive(struct hard_iface *if_incoming, batman_ogm_packet->tt_num_changes)); }
+static int bat_iv_ogm_receive(struct sk_buff *skb, + struct hard_iface *hard_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; + + 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; + + /* packet with broadcast sender address */ + if (is_broadcast_ether_addr(ethhdr->h_source)) + return NET_RX_DROP; + + /* create a copy of the skb, if needed, to modify it. */ + if (skb_cow(skb, 0) < 0) + return NET_RX_DROP; + + /* keep skb linear */ + if (skb_linearize(skb) < 0) + return NET_RX_DROP; + + _bat_iv_ogm_receive(skb, hard_iface); + + kfree_skb(skb); + return NET_RX_SUCCESS; +} + static struct bat_algo_ops batman_iv __read_mostly = { .name = "BATMAN IV", .bat_iface_enable = bat_iv_ogm_iface_enable, @@ -1208,10 +1241,25 @@ static struct bat_algo_ops batman_iv __read_mostly = { .bat_ogm_update_mac = bat_iv_ogm_update_mac, .bat_ogm_schedule = bat_iv_ogm_schedule, .bat_ogm_emit = bat_iv_ogm_emit, - .bat_ogm_receive = bat_iv_ogm_receive, };
int __init bat_iv_init(void) { - return bat_algo_register(&batman_iv); + int ret; + + /* batman originator packet */ + ret = recv_handler_register(BAT_IV_OGM, bat_iv_ogm_receive); + if (ret < 0) + goto out; + + ret = bat_algo_register(&batman_iv); + if (ret < 0) + goto handler_unregister; + + goto out; + +handler_unregister: + recv_handler_unregister(BAT_IV_OGM); +out: + return ret; } diff --git a/main.c b/main.c index 0d0cd48..8c3ff21 100644 --- a/main.c +++ b/main.c @@ -263,8 +263,6 @@ static void recv_handler_init(void) for (i = 0; i < ARRAY_SIZE(recv_packet_handler); i++) recv_packet_handler[i] = recv_unhandled_packet;
- /* batman originator packet */ - recv_packet_handler[BAT_IV_OGM] = recv_bat_ogm_packet; /* batman icmp packet */ recv_packet_handler[BAT_ICMP] = recv_icmp_packet; /* unicast packet */ @@ -331,8 +329,7 @@ int bat_algo_register(struct bat_algo_ops *bat_algo_ops) !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; diff --git a/routing.c b/routing.c index 0da9f5a..9ec4593 100644 --- a/routing.c +++ b/routing.c @@ -248,39 +248,6 @@ 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) -{ - 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; - - 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; - - /* packet with broadcast sender address */ - if (is_broadcast_ether_addr(ethhdr->h_source)) - return NET_RX_DROP; - - /* create a copy of the skb, if needed, to modify it. */ - if (skb_cow(skb, 0) < 0) - return NET_RX_DROP; - - /* keep skb linear */ - if (skb_linearize(skb) < 0) - return NET_RX_DROP; - - bat_priv->bat_algo_ops->bat_ogm_receive(hard_iface, skb); - - kfree_skb(skb); - return NET_RX_SUCCESS; -} - static int recv_my_icmp_packet(struct bat_priv *bat_priv, struct sk_buff *skb, size_t icmp_len) { diff --git a/routing.h b/routing.h index 3d729cb..d69a5a0 100644 --- a/routing.h +++ b/routing.h @@ -30,7 +30,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, diff --git a/types.h b/types.h index 6a3cc88..51c59c2 100644 --- a/types.h +++ b/types.h @@ -408,9 +408,6 @@ struct bat_algo_ops { 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); };
struct dht_candidate {
On Thu, Mar 01, 2012 at 03:35:18PM +0800, Marek Lindner wrote:
-static void bat_iv_ogm_receive(struct hard_iface *if_incoming,
struct sk_buff *skb)
+static void _bat_iv_ogm_receive(struct sk_buff *skb,
struct hard_iface *if_incoming)
<rant> Personally, I don't like underscore functions. They are usually created because of a lack of creativity, but are later called from different places, do different jobs and in the end everyone is confused. :) Is it possibble to change the name, e.g. to bat_iv_ogm_handle()? </rant>
{ struct batman_ogm_packet *batman_ogm_packet; struct ethhdr *ethhdr; @@ -1200,6 +1200,39 @@ static void bat_iv_ogm_receive(struct hard_iface *if_incoming, batman_ogm_packet->tt_num_changes)); }
+static int bat_iv_ogm_receive(struct sk_buff *skb,
struct hard_iface *hard_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;
- 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;
- /* packet with broadcast sender address */
- if (is_broadcast_ether_addr(ethhdr->h_source))
return NET_RX_DROP;
- /* create a copy of the skb, if needed, to modify it. */
- if (skb_cow(skb, 0) < 0)
return NET_RX_DROP;
- /* keep skb linear */
- if (skb_linearize(skb) < 0)
return NET_RX_DROP;
- _bat_iv_ogm_receive(skb, hard_iface);
- kfree_skb(skb);
- return NET_RX_SUCCESS;
+}
We should somewhere add a check whether the hard_iface is actually assigned to a mesh using the BATMAN IV algorithm. When more algorithms are added, we only want the assigned protocol to be handled, others should be ignored.
Cheers, Simon
On Sunday, March 04, 2012 01:59:53 Simon Wunderlich wrote:
On Thu, Mar 01, 2012 at 03:35:18PM +0800, Marek Lindner wrote:
-static void bat_iv_ogm_receive(struct hard_iface *if_incoming,
struct sk_buff *skb)
+static void _bat_iv_ogm_receive(struct sk_buff *skb,
struct hard_iface *if_incoming)
<rant> Personally, I don't like underscore functions. They are usually created because of a lack of creativity, but are later called from different places, do different jobs and in the end everyone is confused. :) Is it possibble to change the name, e.g. to bat_iv_ogm_handle()? </rant>
Hmm.., I kind of agree. I'll think about another solution. :-)
We should somewhere add a check whether the hard_iface is actually assigned to a mesh using the BATMAN IV algorithm. When more algorithms are added, we only want the assigned protocol to be handled, others should be ignored.
You are right - we need a check but not necessarily in this patch. We lived without such a check for quite while. This patch is not introducing a loophole that did not exist before. I'll send a separate patch.
Thanks for the comments!
Cheers, Marek
The B.A.T.M.A.N. IV OGM receive function still was hard-coded although it is a routing protocol specific function. This patch takes advantage of the dynamic packet handler registration to remove the hard-coded function calls.
Signed-off-by: Marek Lindner lindner_marek@yahoo.de --- bat_iv_ogm.c | 31 +++++++++++++++++++++++++++---- main.c | 5 +---- routing.c | 22 ++++++++++------------ routing.h | 4 +++- types.h | 3 --- 5 files changed, 41 insertions(+), 24 deletions(-)
diff --git a/bat_iv_ogm.c b/bat_iv_ogm.c index aba0204..784fcef 100644 --- a/bat_iv_ogm.c +++ b/bat_iv_ogm.c @@ -1166,13 +1166,18 @@ out: orig_node_free_ref(orig_node); }
-static void bat_iv_ogm_receive(struct hard_iface *if_incoming, - struct sk_buff *skb) +static int bat_iv_ogm_receive(struct sk_buff *skb, + struct hard_iface *if_incoming) { struct batman_ogm_packet *batman_ogm_packet; struct ethhdr *ethhdr; int buff_pos = 0, packet_len; unsigned char *tt_buff, *packet_buff; + bool ret; + + ret = check_management_packet(skb, if_incoming, BATMAN_OGM_HLEN); + if (!ret) + return NET_RX_DROP;
packet_len = skb_headlen(skb); ethhdr = (struct ethhdr *)skb_mac_header(skb); @@ -1198,6 +1203,9 @@ static void bat_iv_ogm_receive(struct hard_iface *if_incoming, (packet_buff + buff_pos); } while (bat_iv_ogm_aggr_packet(buff_pos, packet_len, batman_ogm_packet->tt_num_changes)); + + kfree_skb(skb); + return NET_RX_SUCCESS; }
static struct bat_algo_ops batman_iv __read_mostly = { @@ -1208,10 +1216,25 @@ static struct bat_algo_ops batman_iv __read_mostly = { .bat_ogm_update_mac = bat_iv_ogm_update_mac, .bat_ogm_schedule = bat_iv_ogm_schedule, .bat_ogm_emit = bat_iv_ogm_emit, - .bat_ogm_receive = bat_iv_ogm_receive, };
int __init bat_iv_init(void) { - return bat_algo_register(&batman_iv); + int ret; + + /* batman originator packet */ + ret = recv_handler_register(BAT_IV_OGM, bat_iv_ogm_receive); + if (ret < 0) + goto out; + + ret = bat_algo_register(&batman_iv); + if (ret < 0) + goto handler_unregister; + + goto out; + +handler_unregister: + recv_handler_unregister(BAT_IV_OGM); +out: + return ret; } diff --git a/main.c b/main.c index 0d0cd48..8c3ff21 100644 --- a/main.c +++ b/main.c @@ -263,8 +263,6 @@ static void recv_handler_init(void) for (i = 0; i < ARRAY_SIZE(recv_packet_handler); i++) recv_packet_handler[i] = recv_unhandled_packet;
- /* batman originator packet */ - recv_packet_handler[BAT_IV_OGM] = recv_bat_ogm_packet; /* batman icmp packet */ recv_packet_handler[BAT_ICMP] = recv_icmp_packet; /* unicast packet */ @@ -331,8 +329,7 @@ int bat_algo_register(struct bat_algo_ops *bat_algo_ops) !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; diff --git a/routing.c b/routing.c index 0da9f5a..d83502a 100644 --- a/routing.c +++ b/routing.c @@ -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, diff --git a/routing.h b/routing.h index 3d729cb..d6bbbeb 100644 --- a/routing.h +++ b/routing.h @@ -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, diff --git a/types.h b/types.h index 6a3cc88..51c59c2 100644 --- a/types.h +++ b/types.h @@ -408,9 +408,6 @@ struct bat_algo_ops { 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); };
struct dht_candidate {
Hey Marek,
this looks much cleaner. Thanks! Simon
Acked-by: Simon Wunderlich siwu@hrz.tu-chemnitz.de
On Sun, Mar 04, 2012 at 04:56:25PM +0800, Marek Lindner wrote:
The B.A.T.M.A.N. IV OGM receive function still was hard-coded although it is a routing protocol specific function. This patch takes advantage of the dynamic packet handler registration to remove the hard-coded function calls.
Signed-off-by: Marek Lindner lindner_marek@yahoo.de
bat_iv_ogm.c | 31 +++++++++++++++++++++++++++---- main.c | 5 +---- routing.c | 22 ++++++++++------------ routing.h | 4 +++- types.h | 3 --- 5 files changed, 41 insertions(+), 24 deletions(-)
diff --git a/bat_iv_ogm.c b/bat_iv_ogm.c index aba0204..784fcef 100644 --- a/bat_iv_ogm.c +++ b/bat_iv_ogm.c @@ -1166,13 +1166,18 @@ out: orig_node_free_ref(orig_node); }
-static void bat_iv_ogm_receive(struct hard_iface *if_incoming,
struct sk_buff *skb)
+static int bat_iv_ogm_receive(struct sk_buff *skb,
struct hard_iface *if_incoming)
{ struct batman_ogm_packet *batman_ogm_packet; struct ethhdr *ethhdr; int buff_pos = 0, packet_len; unsigned char *tt_buff, *packet_buff;
bool ret;
ret = check_management_packet(skb, if_incoming, BATMAN_OGM_HLEN);
if (!ret)
return NET_RX_DROP;
packet_len = skb_headlen(skb); ethhdr = (struct ethhdr *)skb_mac_header(skb);
@@ -1198,6 +1203,9 @@ static void bat_iv_ogm_receive(struct hard_iface *if_incoming, (packet_buff + buff_pos); } while (bat_iv_ogm_aggr_packet(buff_pos, packet_len, batman_ogm_packet->tt_num_changes));
- kfree_skb(skb);
- return NET_RX_SUCCESS;
}
static struct bat_algo_ops batman_iv __read_mostly = { @@ -1208,10 +1216,25 @@ static struct bat_algo_ops batman_iv __read_mostly = { .bat_ogm_update_mac = bat_iv_ogm_update_mac, .bat_ogm_schedule = bat_iv_ogm_schedule, .bat_ogm_emit = bat_iv_ogm_emit,
- .bat_ogm_receive = bat_iv_ogm_receive,
};
int __init bat_iv_init(void) {
- return bat_algo_register(&batman_iv);
- int ret;
- /* batman originator packet */
- ret = recv_handler_register(BAT_IV_OGM, bat_iv_ogm_receive);
- if (ret < 0)
goto out;
- ret = bat_algo_register(&batman_iv);
- if (ret < 0)
goto handler_unregister;
- goto out;
+handler_unregister:
- recv_handler_unregister(BAT_IV_OGM);
+out:
- return ret;
} diff --git a/main.c b/main.c index 0d0cd48..8c3ff21 100644 --- a/main.c +++ b/main.c @@ -263,8 +263,6 @@ static void recv_handler_init(void) for (i = 0; i < ARRAY_SIZE(recv_packet_handler); i++) recv_packet_handler[i] = recv_unhandled_packet;
- /* batman originator packet */
- recv_packet_handler[BAT_IV_OGM] = recv_bat_ogm_packet; /* batman icmp packet */ recv_packet_handler[BAT_ICMP] = recv_icmp_packet; /* unicast packet */
@@ -331,8 +329,7 @@ int bat_algo_register(struct bat_algo_ops *bat_algo_ops) !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) {
pr_info("Routing algo '%s' does not implement required ops\n", bat_algo_ops->name); goto out;!bat_algo_ops->bat_ogm_emit) {
diff --git a/routing.c b/routing.c index 0da9f5a..d83502a 100644 --- a/routing.c +++ b/routing.c @@ -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, diff --git a/routing.h b/routing.h index 3d729cb..d6bbbeb 100644 --- a/routing.h +++ b/routing.h @@ -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, diff --git a/types.h b/types.h index 6a3cc88..51c59c2 100644 --- a/types.h +++ b/types.h @@ -408,9 +408,6 @@ struct bat_algo_ops { 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);
};
struct dht_candidate {
1.7.9
On Sunday, March 04, 2012 16:56:25 Marek Lindner wrote:
The B.A.T.M.A.N. IV OGM receive function still was hard-coded although it is a routing protocol specific function. This patch takes advantage of the dynamic packet handler registration to remove the hard-coded function calls.
Applied in revision 9f72fc2.
Regards, Marek
Signed-off-by: Marek Lindner lindner_marek@yahoo.de --- bat_iv_ogm.c | 8 ++++---- originator.c | 16 ++++++++-------- types.h | 8 ++++---- 3 files changed, 16 insertions(+), 16 deletions(-)
diff --git a/bat_iv_ogm.c b/bat_iv_ogm.c index 5833a3e..209722f 100644 --- a/bat_iv_ogm.c +++ b/bat_iv_ogm.c @@ -655,7 +655,7 @@ static void bat_iv_ogm_orig_update(struct bat_priv *bat_priv, rcu_read_unlock();
orig_node->flags = batman_ogm_packet->flags; - neigh_node->last_valid = jiffies; + neigh_node->last_seen = jiffies;
spin_lock_bh(&neigh_node->tq_lock); ring_buffer_set(neigh_node->tq_recv, @@ -776,11 +776,11 @@ static int bat_iv_ogm_calc_tq(struct orig_node *orig_node, if (!neigh_node) goto out;
- /* if orig_node is direct neighbor update neigh_node last_valid */ + /* if orig_node is direct neighbor update neigh_node last_seen */ if (orig_node == orig_neigh_node) - neigh_node->last_valid = jiffies; + neigh_node->last_seen = jiffies;
- orig_node->last_valid = jiffies; + orig_node->last_seen = jiffies;
/* find packet count of corresponding one hop neighbor */ spin_lock_bh(&orig_node->ogm_cnt_lock); diff --git a/originator.c b/originator.c index 06c8187..aa33337 100644 --- a/originator.c +++ b/originator.c @@ -285,7 +285,7 @@ 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)) { @@ -304,9 +304,9 @@ static bool purge_orig_neighbors(struct bat_priv *bat_priv, else bat_dbg(DBG_BATMAN, bat_priv, "neighbor timeout: originator %pM, " - "neighbor: %pM, last_valid: %lu\n", + "neighbor: %pM, last_seen: %lu\n", orig_node->orig, neigh_node->addr, - (neigh_node->last_valid / HZ)); + (neigh_node->last_seen / HZ));
neigh_purged = true;
@@ -329,10 +329,10 @@ 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 %lu\n", + orig_node->orig, (orig_node->last_seen / HZ)); return true; } else { if (purge_orig_neighbors(bat_priv, orig_node, @@ -450,9 +450,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, diff --git a/types.h b/types.h index 51c59c2..0643271 100644 --- a/types.h +++ b/types.h @@ -64,7 +64,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 @@ -85,7 +85,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; @@ -135,7 +135,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; @@ -146,7 +146,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;
On Thursday, March 01, 2012 15:35:19 Marek Lindner wrote:
Signed-off-by: Marek Lindner lindner_marek@yahoo.de
bat_iv_ogm.c | 8 ++++---- originator.c | 16 ++++++++-------- types.h | 8 ++++---- 3 files changed, 16 insertions(+), 16 deletions(-)
Applied in revision 02b4338.
Regards, Marek
Signed-off-by: Marek Lindner lindner_marek@yahoo.de --- bat_debugfs.c | 4 ++-- originator.c | 15 ++++++++++----- send.c | 2 +- 3 files changed, 13 insertions(+), 8 deletions(-)
diff --git a/bat_debugfs.c b/bat_debugfs.c index 916380c..3b588f8 100644 --- a/bat_debugfs.c +++ b/bat_debugfs.c @@ -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; diff --git a/originator.c b/originator.c index aa33337..183a1fe 100644 --- a/originator.c +++ b/originator.c @@ -36,7 +36,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 */ @@ -276,6 +277,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;
@@ -290,6 +292,8 @@ static bool purge_orig_neighbors(struct bat_priv *bat_priv, (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 == @@ -304,9 +308,9 @@ static bool purge_orig_neighbors(struct bat_priv *bat_priv, else bat_dbg(DBG_BATMAN, bat_priv, "neighbor timeout: originator %pM, " - "neighbor: %pM, last_seen: %lu\n", + "neighbor: %pM, last_seen: %u\n", orig_node->orig, neigh_node->addr, - (neigh_node->last_seen / HZ)); + jiffies_to_msecs(last_seen));
neigh_purged = true;
@@ -331,8 +335,9 @@ static bool purge_orig_node(struct bat_priv *bat_priv,
if (has_timed_out(orig_node->last_seen, 2 * PURGE_TIMEOUT)) { bat_dbg(DBG_BATMAN, bat_priv, - "Originator timeout: originator %pM, last_seen %lu\n", - orig_node->orig, (orig_node->last_seen / 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, diff --git a/send.c b/send.c index f7f5e3a..0d01e2b 100644 --- a/send.c +++ b/send.c @@ -296,7 +296,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; }
On Thursday, March 01, 2012 15:35:20 Marek Lindner wrote:
Signed-off-by: Marek Lindner lindner_marek@yahoo.de
bat_debugfs.c | 4 ++-- originator.c | 15 ++++++++++----- send.c | 2 +- 3 files changed, 13 insertions(+), 8 deletions(-)
Applied in revision bfe9936.
Regards, Marek
Signed-off-by: Marek Lindner lindner_marek@yahoo.de --- bat_iv_ogm.c | 40 ++++++++++++++++++++++++++++++++++------ originator.c | 27 ++++++++++----------------- originator.h | 6 ++---- 3 files changed, 46 insertions(+), 27 deletions(-)
diff --git a/bat_iv_ogm.c b/bat_iv_ogm.c index 209722f..2d2cc73 100644 --- a/bat_iv_ogm.c +++ b/bat_iv_ogm.c @@ -30,6 +30,32 @@ #include "send.h" #include "bat_algo.h"
+static struct neigh_node *bat_iv_ogm_neigh_new(struct hard_iface *hard_iface, + const uint8_t *neigh_addr, + struct orig_node *orig_node, + struct orig_node *orig_neigh, + uint32_t seqno) +{ + struct neigh_node *neigh_node; + + neigh_node = neigh_node_new(hard_iface, neigh_addr, seqno); + if (!neigh_node) + goto out; + + INIT_LIST_HEAD(&neigh_node->bonding_list); + spin_lock_init(&neigh_node->tq_lock); + + neigh_node->orig_node = orig_neigh; + neigh_node->if_incoming = hard_iface; + + 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); + +out: + return neigh_node; +} + static int bat_iv_ogm_iface_enable(struct hard_iface *hard_iface) { struct batman_ogm_packet *batman_ogm_packet; @@ -642,8 +668,9 @@ static void bat_iv_ogm_orig_update(struct bat_priv *bat_priv, if (!orig_tmp) goto unlock;
- neigh_node = create_neighbor(orig_node, orig_tmp, - ethhdr->h_source, if_incoming); + neigh_node = bat_iv_ogm_neigh_new(if_incoming, ethhdr->h_source, + orig_node, orig_tmp, + batman_ogm_packet->seqno);
orig_node_free_ref(orig_tmp); if (!neigh_node) @@ -768,10 +795,11 @@ static int bat_iv_ogm_calc_tq(struct orig_node *orig_node, rcu_read_unlock();
if (!neigh_node) - neigh_node = create_neighbor(orig_neigh_node, - orig_neigh_node, - orig_neigh_node->orig, - if_incoming); + neigh_node = bat_iv_ogm_neigh_new(if_incoming, + orig_neigh_node->orig, + orig_neigh_node, + orig_neigh_node, + batman_ogm_packet->seqno);
if (!neigh_node) goto out; diff --git a/originator.c b/originator.c index 183a1fe..9f32aa0 100644 --- a/originator.c +++ b/originator.c @@ -86,35 +86,28 @@ 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 *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; }
diff --git a/originator.h b/originator.h index 3fe2eda..64c5d94 100644 --- a/originator.h +++ b/originator.h @@ -29,10 +29,8 @@ 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 *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);
On Thursday, March 01, 2012 15:35:21 Marek Lindner wrote:
Signed-off-by: Marek Lindner lindner_marek@yahoo.de
bat_iv_ogm.c | 40 ++++++++++++++++++++++++++++++++++------ originator.c | 27 ++++++++++----------------- originator.h | 6 ++---- 3 files changed, 46 insertions(+), 27 deletions(-)
Applied in revision 0c9a249.
Regards, Marek
Hey Marek,
I did a rough review over your patches, and a more detailed one to the HZ/jiffies patch. Looks fine, nice approach to get some more compatibility in. You've also added the handler table from our beer discussion - nice. ;)
Apart from some minor comments on patch no. 3, feel free to add
Acked-by: Simon Wunderlich siwu@hrz.tu-chemnitz.de
to all the patches.
Cheers, Simon
On Thursday, March 01, 2012 15:35:16 Marek Lindner wrote:
Signed-off-by: Marek Lindner lindner_marek@yahoo.de
bat_iv_ogm.c | 16 +++++++++------- 1 files changed, 9 insertions(+), 7 deletions(-)
Applied in revision 94df16a.
Regards, Marek
b.a.t.m.a.n@lists.open-mesh.org