From: Simon Wunderlich simon@open-mesh.com
To match our code better to the protocol description of B.A.T.M.A.N. V, move batadv_v_ogm_forward() out into batadv_v_ogm_process_per_outif() and move all checks directly deciding whether the OGM should be forwarded into batadv_v_ogm_forward().
Signed-off-by: Simon Wunderlich simon@open-mesh.com --- Changes to PATCH: * fix some embarassing compile issues and style issues (thanks Marek) --- net/batman-adv/bat_v_ogm.c | 110 ++++++++++++++++++++++++++------------------- 1 file changed, 63 insertions(+), 47 deletions(-)
diff --git a/net/batman-adv/bat_v_ogm.c b/net/batman-adv/bat_v_ogm.c index d9bcbe6..341ff27 100644 --- a/net/batman-adv/bat_v_ogm.c +++ b/net/batman-adv/bat_v_ogm.c @@ -347,10 +347,12 @@ static u32 batadv_v_forward_penalty(struct batadv_priv *bat_priv, }
/** - * batadv_v_ogm_forward - forward an OGM to the given outgoing interface + * batadv_v_ogm_forward - check conditions and forward an OGM to the given + * outgoing interface * @bat_priv: the bat priv with all the soft interface information * @ogm_received: previously received OGM to be forwarded - * @throughput: throughput to announce, may vary per outgoing interface + * @orig_node: the originator which has been updated + * @neigh_node: the neigh_node through with the OGM has been received * @if_incoming: the interface on which this OGM was received on * @if_outgoing: the interface to which the OGM has to be forwarded to * @@ -359,28 +361,57 @@ static u32 batadv_v_forward_penalty(struct batadv_priv *bat_priv, */ static void batadv_v_ogm_forward(struct batadv_priv *bat_priv, const struct batadv_ogm2_packet *ogm_received, - u32 throughput, + struct batadv_orig_node *orig_node, + struct batadv_neigh_node *neigh_node, struct batadv_hard_iface *if_incoming, struct batadv_hard_iface *if_outgoing) { + struct batadv_neigh_ifinfo *neigh_ifinfo = NULL; + struct batadv_orig_ifinfo *orig_ifinfo = NULL; + struct batadv_neigh_node *router = NULL; struct batadv_ogm2_packet *ogm_forward; unsigned char *skb_buff; struct sk_buff *skb; size_t packet_len; u16 tvlv_len;
+ /* only forward for specific interfaces, not for the default one. */ + if (if_outgoing != BATADV_IF_DEFAULT) + goto out; + + orig_ifinfo = batadv_orig_ifinfo_new(orig_node, if_outgoing); + if (!orig_ifinfo) + goto out; + + /* acquire possibly updated router */ + router = batadv_orig_router_get(orig_node, if_outgoing); + + /* strict rule: forward packets coming from the best next hop only */ + if (neigh_node != router) + goto out; + + /* don't forward the same seqno twice on one interface */ + if (orig_ifinfo->last_seqno_forwarded == ntohl(ogm_received->seqno)) + goto out; + + orig_ifinfo->last_seqno_forwarded = ntohl(ogm_received->seqno); + if (ogm_received->ttl <= 1) { batadv_dbg(BATADV_DBG_BATMAN, bat_priv, "ttl exceeded\n"); - return; + goto out; }
+ neigh_ifinfo = batadv_neigh_ifinfo_get(neigh_node, if_outgoing); + if (!neigh_ifinfo) + goto out; + tvlv_len = ntohs(ogm_received->tvlv_len);
packet_len = BATADV_OGM2_HLEN + tvlv_len; skb = netdev_alloc_skb_ip_align(if_outgoing->net_dev, ETH_HLEN + packet_len); if (!skb) - return; + goto out;
skb_reserve(skb, ETH_HLEN); skb_buff = skb_put(skb, packet_len); @@ -388,15 +419,23 @@ static void batadv_v_ogm_forward(struct batadv_priv *bat_priv,
/* apply forward penalty */ ogm_forward = (struct batadv_ogm2_packet *)skb_buff; - ogm_forward->throughput = htonl(throughput); + ogm_forward->throughput = htonl(neigh_ifinfo->bat_v.throughput); ogm_forward->ttl--;
batadv_dbg(BATADV_DBG_BATMAN, bat_priv, "Forwarding OGM2 packet on %s: throughput %u, ttl %u, received via %s\n", - if_outgoing->net_dev->name, throughput, ogm_forward->ttl, - if_incoming->net_dev->name); + if_outgoing->net_dev->name, ntohl(ogm_forward->throughput), + ogm_forward->ttl, if_incoming->net_dev->name);
batadv_v_ogm_send_to_if(skb, if_outgoing); + +out: + if (orig_ifinfo) + batadv_orig_ifinfo_put(orig_ifinfo); + if (router) + batadv_neigh_node_put(router); + if (neigh_ifinfo) + batadv_neigh_ifinfo_put(neigh_ifinfo); }
/** @@ -493,8 +532,10 @@ out: * @neigh_node: the neigh_node through with the OGM has been received * @if_incoming: the interface where this packet was received * @if_outgoing: the interface for which the packet should be considered + * + * Return: true if the packet should be forwarded, false otherwise */ -static void batadv_v_ogm_route_update(struct batadv_priv *bat_priv, +static bool batadv_v_ogm_route_update(struct batadv_priv *bat_priv, const struct ethhdr *ethhdr, const struct batadv_ogm2_packet *ogm2, struct batadv_orig_node *orig_node, @@ -503,14 +544,9 @@ static void batadv_v_ogm_route_update(struct batadv_priv *bat_priv, struct batadv_hard_iface *if_outgoing) { struct batadv_neigh_node *router = NULL; - struct batadv_neigh_ifinfo *neigh_ifinfo = NULL; struct batadv_orig_node *orig_neigh_node = NULL; - struct batadv_orig_ifinfo *orig_ifinfo = NULL; struct batadv_neigh_node *orig_neigh_router = NULL; - - neigh_ifinfo = batadv_neigh_ifinfo_get(neigh_node, if_outgoing); - if (!neigh_ifinfo) - goto out; + bool forward = false;
orig_neigh_node = batadv_v_ogm_orig_get(bat_priv, ethhdr->h_source); if (!orig_neigh_node) @@ -529,47 +565,20 @@ static void batadv_v_ogm_route_update(struct batadv_priv *bat_priv, goto out; }
- if (router) - batadv_neigh_node_put(router); - /* Update routes, and check if the OGM is from the best next hop */ batadv_v_ogm_orig_update(bat_priv, orig_node, neigh_node, ogm2, if_outgoing);
- orig_ifinfo = batadv_orig_ifinfo_new(orig_node, if_outgoing); - if (!orig_ifinfo) - goto out; - - /* don't forward the same seqno twice on one interface */ - if (orig_ifinfo->last_seqno_forwarded == ntohl(ogm2->seqno)) - goto out; - - /* acquire possibly updated router */ - router = batadv_orig_router_get(orig_node, if_outgoing); - - /* strict rule: forward packets coming from the best next hop only */ - if (neigh_node != router) - goto out; - - /* only forward for specific interface, not for the default one. */ - if (if_outgoing != BATADV_IF_DEFAULT) { - orig_ifinfo->last_seqno_forwarded = ntohl(ogm2->seqno); - batadv_v_ogm_forward(bat_priv, ogm2, - neigh_ifinfo->bat_v.throughput, - if_incoming, if_outgoing); - } - + forward = true; out: - if (orig_ifinfo) - batadv_orig_ifinfo_put(orig_ifinfo); if (router) batadv_neigh_node_put(router); if (orig_neigh_router) batadv_neigh_node_put(orig_neigh_router); if (orig_neigh_node) batadv_orig_node_put(orig_neigh_node); - if (neigh_ifinfo) - batadv_neigh_ifinfo_put(neigh_ifinfo); + + return forward; }
/** @@ -592,6 +601,7 @@ batadv_v_ogm_process_per_outif(struct batadv_priv *bat_priv, struct batadv_hard_iface *if_outgoing) { int seqno_age; + bool forward;
/* first, update the metric with according sanity checks */ seqno_age = batadv_v_ogm_metric_update(bat_priv, ogm2, orig_node, @@ -610,8 +620,14 @@ batadv_v_ogm_process_per_outif(struct batadv_priv *bat_priv, ntohs(ogm2->tvlv_len));
/* if the metric update went through, update routes if needed */ - batadv_v_ogm_route_update(bat_priv, ethhdr, ogm2, orig_node, - neigh_node, if_incoming, if_outgoing); + forward = batadv_v_ogm_route_update(bat_priv, ethhdr, ogm2, orig_node, + neigh_node, if_incoming, + if_outgoing); + + /* if the routes have been processed correctly, check and forward */ + if (forward) + batadv_v_ogm_forward(bat_priv, ogm2, orig_node, neigh_node, + if_incoming, if_outgoing); }
/**
From: Simon Wunderlich simon@open-mesh.com
Since batadv_v_ogm_orig_update() was only called from one place and the calling function became very short, merge these two functions together.
This should also reflect the protocol description of B.A.T.M.A.N. V better.
Signed-off-by: Simon Wunderlich simon@open-mesh.com --- net/batman-adv/bat_v_ogm.c | 117 ++++++++++++++++++--------------------------- 1 file changed, 46 insertions(+), 71 deletions(-)
diff --git a/net/batman-adv/bat_v_ogm.c b/net/batman-adv/bat_v_ogm.c index 341ff27..1b2399e 100644 --- a/net/batman-adv/bat_v_ogm.c +++ b/net/batman-adv/bat_v_ogm.c @@ -234,73 +234,6 @@ void batadv_v_ogm_primary_iface_set(struct batadv_hard_iface *primary_iface) }
/** - * batadv_v_ogm_orig_update - update the originator status based on the received - * OGM - * @bat_priv: the bat priv with all the soft interface information - * @orig_node: the originator to update - * @neigh_node: the neighbour the OGM has been received from (to update) - * @ogm2: the received OGM - * @if_outgoing: the interface where this OGM is going to be forwarded through - */ -static void -batadv_v_ogm_orig_update(struct batadv_priv *bat_priv, - struct batadv_orig_node *orig_node, - struct batadv_neigh_node *neigh_node, - const struct batadv_ogm2_packet *ogm2, - struct batadv_hard_iface *if_outgoing) -{ - struct batadv_neigh_ifinfo *router_ifinfo = NULL, *neigh_ifinfo = NULL; - struct batadv_neigh_node *router = NULL; - s32 neigh_seq_diff; - u32 neigh_last_seqno; - u32 router_last_seqno; - u32 router_throughput, neigh_throughput; - - batadv_dbg(BATADV_DBG_BATMAN, bat_priv, - "Searching and updating originator entry of received packet\n"); - - /* if this neighbor already is our next hop there is nothing - * to change - */ - router = batadv_orig_router_get(orig_node, if_outgoing); - if (router == neigh_node) - goto out; - - /* don't consider neighbours with worse throughput. - * also switch route if this seqno is BATADV_V_MAX_ORIGDIFF newer than - * the last received seqno from our best next hop. - */ - if (router) { - router_ifinfo = batadv_neigh_ifinfo_get(router, if_outgoing); - neigh_ifinfo = batadv_neigh_ifinfo_get(neigh_node, if_outgoing); - - /* if these are not allocated, something is wrong. */ - if (!router_ifinfo || !neigh_ifinfo) - goto out; - - neigh_last_seqno = neigh_ifinfo->bat_v.last_seqno; - router_last_seqno = router_ifinfo->bat_v.last_seqno; - neigh_seq_diff = neigh_last_seqno - router_last_seqno; - router_throughput = router_ifinfo->bat_v.throughput; - neigh_throughput = neigh_ifinfo->bat_v.throughput; - - if ((neigh_seq_diff < BATADV_OGM_MAX_ORIGDIFF) && - (router_throughput >= neigh_throughput)) - goto out; - } - - batadv_update_route(bat_priv, orig_node, if_outgoing, neigh_node); - -out: - if (router_ifinfo) - batadv_neigh_ifinfo_put(router_ifinfo); - if (neigh_ifinfo) - batadv_neigh_ifinfo_put(neigh_ifinfo); - if (router) - batadv_neigh_node_put(router); -} - -/** * batadv_v_forward_penalty - apply a penalty to the throughput metric forwarded * with B.A.T.M.A.N. V OGMs * @bat_priv: the bat priv with all the soft interface information @@ -546,6 +479,11 @@ static bool batadv_v_ogm_route_update(struct batadv_priv *bat_priv, struct batadv_neigh_node *router = NULL; struct batadv_orig_node *orig_neigh_node = NULL; struct batadv_neigh_node *orig_neigh_router = NULL; + struct batadv_neigh_ifinfo *router_ifinfo = NULL, *neigh_ifinfo = NULL; + u32 router_throughput, neigh_throughput; + u32 router_last_seqno; + u32 neigh_last_seqno; + s32 neigh_seq_diff; bool forward = false;
orig_neigh_node = batadv_v_ogm_orig_get(bat_priv, ethhdr->h_source); @@ -565,11 +503,44 @@ static bool batadv_v_ogm_route_update(struct batadv_priv *bat_priv, goto out; }
- /* Update routes, and check if the OGM is from the best next hop */ - batadv_v_ogm_orig_update(bat_priv, orig_node, neigh_node, ogm2, - if_outgoing); - + /* Mark the OGM to be considered for forwarding, and update routes + * if needed. + */ forward = true; + + batadv_dbg(BATADV_DBG_BATMAN, bat_priv, + "Searching and updating originator entry of received packet\n"); + + /* if this neighbor already is our next hop there is nothing + * to change + */ + if (router == neigh_node) + goto out; + + /* don't consider neighbours with worse throughput. + * also switch route if this seqno is BATADV_V_MAX_ORIGDIFF newer than + * the last received seqno from our best next hop. + */ + if (router) { + router_ifinfo = batadv_neigh_ifinfo_get(router, if_outgoing); + neigh_ifinfo = batadv_neigh_ifinfo_get(neigh_node, if_outgoing); + + /* if these are not allocated, something is wrong. */ + if (!router_ifinfo || !neigh_ifinfo) + goto out; + + neigh_last_seqno = neigh_ifinfo->bat_v.last_seqno; + router_last_seqno = router_ifinfo->bat_v.last_seqno; + neigh_seq_diff = neigh_last_seqno - router_last_seqno; + router_throughput = router_ifinfo->bat_v.throughput; + neigh_throughput = neigh_ifinfo->bat_v.throughput; + + if ((neigh_seq_diff < BATADV_OGM_MAX_ORIGDIFF) && + (router_throughput >= neigh_throughput)) + goto out; + } + + batadv_update_route(bat_priv, orig_node, if_outgoing, neigh_node); out: if (router) batadv_neigh_node_put(router); @@ -577,6 +548,10 @@ out: batadv_neigh_node_put(orig_neigh_router); if (orig_neigh_node) batadv_orig_node_put(orig_neigh_node); + if (router_ifinfo) + batadv_neigh_ifinfo_put(router_ifinfo); + if (neigh_ifinfo) + batadv_neigh_ifinfo_put(neigh_ifinfo);
return forward; }
On Monday, February 01, 2016 15:21:38 Simon Wunderlich wrote:
From: Simon Wunderlich simon@open-mesh.com
Since batadv_v_ogm_orig_update() was only called from one place and the calling function became very short, merge these two functions together.
This should also reflect the protocol description of B.A.T.M.A.N. V better.
Signed-off-by: Simon Wunderlich simon@open-mesh.com
net/batman-adv/bat_v_ogm.c | 117 ++++++++++++++++++--------------------------- 1 file changed, 46 insertions(+), 71 deletions(-)
Applied in revision 507dba0.
Thanks, Marek
On Monday, February 01, 2016 15:21:37 Simon Wunderlich wrote:
From: Simon Wunderlich simon@open-mesh.com
To match our code better to the protocol description of B.A.T.M.A.N. V, move batadv_v_ogm_forward() out into batadv_v_ogm_process_per_outif() and move all checks directly deciding whether the OGM should be forwarded into batadv_v_ogm_forward().
Signed-off-by: Simon Wunderlich simon@open-mesh.com
Changes to PATCH:
- fix some embarassing compile issues and style issues (thanks Marek)
net/batman-adv/bat_v_ogm.c | 110 ++++++++++++++++++++++++++------------------- 1 file changed, 63 insertions(+), 47 deletions(-)
Applied in revision 30c96bc.
Thanks, Marek
On Monday 01 February 2016 15:21:37 Simon Wunderlich wrote:
From: Simon Wunderlich simon@open-mesh.com
To match our code better to the protocol description of B.A.T.M.A.N. V, move batadv_v_ogm_forward() out into batadv_v_ogm_process_per_outif() and move all checks directly deciding whether the OGM should be forwarded into batadv_v_ogm_forward().
Signed-off-by: Simon Wunderlich simon@open-mesh.com
Changes to PATCH:
- fix some embarassing compile issues and style issues (thanks Marek)
This patch crashes my two node test setup (2xOM2P-HS).
/etc/config/wireless: ====================
config wifi-iface 'wmesh' option device 'radio0' option ifname 'adhoc0' option network 'batnet' option mode 'adhoc' option ssid 'mesh' option 'mcast_rate' '18000' option bssid '02:CA:FE:CA:CA:40'
/etc/config/network ===================
config interface 'batnet' option mtu '1532' option proto 'batadv' option mesh 'bat0' option routing_algo 'BATMAN_V'
[ 21.690000] CPU 0 Unable to handle kernel paging request at virtual address 0000000c, epc == 83183d04, ra == 83183cf8 [ 21.700000] Oops[#1]: [ 21.700000] CPU: 0 PID: 1152 Comm: udhcpc Tainted: P 3.18.8 #1 [ 21.700000] task: 83987070 ti: 8298e000 task.ti: 8298e000 [ 21.700000] $ 0 : 00000000 00000001 8297b400 00000001 [ 21.700000] $ 4 : 00000001 00000000 00000002 82980100 [ 21.700000] $ 8 : 00000001 0000ed7e 8297b380 c881c661 [ 21.700000] $12 : 00000000 832cf499 00000000 7fc3a8d0 [ 21.700000] $16 : 82808090 00000000 82980100 8297b400 [ 21.700000] $20 : 82951a00 8297b680 0000001c 00000000 [ 21.700000] $24 : 00000000 8021f434 [ 21.700000] $28 : 8298e000 8298f968 82951a00 83183cf8 [ 21.700000] Hi : 000003b7 [ 21.700000] Lo : 003f2fb0 [ 21.700000] epc : 83183d04 batadv_v_ogm_orig_get+0x65c/0x738 [batman_adv] [ 21.700000] Tainted: P [ 21.700000] ra : 83183cf8 batadv_v_ogm_orig_get+0x650/0x738 [batman_adv] [ 21.700000] Status: 1100f403 KERNEL EXL IE [ 21.700000] Cause : 00800008 [ 21.700000] BadVA : 0000000c [ 21.700000] PrId : 0001974c (MIPS 74Kc) [ 21.700000] Modules linked in: iptable_nat ath9k nf_nat_pptp nf_nat_ipv4 nf_nat_amanda nf_conntrack_pptp nf_conntrack_ipv6 nf_conntrack_ipv4 nf_conntrack_amanda ipt_REJECT ipt_MASQUERADE ath9k_common xt_time xt_tcpudp xt_tcpmss xt_string xt_statistic xt_state xt_recent xt_quota xt_pkttype xt_physdev xt_owner xt_nat xt_multiport xt_mark xt_mac xt_limit xt_length xt_id xt_hl xt_helper xt_ecn xt_dscp xt_conntrack xt_connmark xt_connlimit xt_connbytes xt_comment xt_addrtype xt_TCPMSS xt_REDIRECT xt_NETMAP xt_LOG xt_HL xt_DSCP xt_CT xt_CLASSIFY ts_kmp ts_fsm ts_bm nf_reject_ipv4 nf_nat_tftp nf_nat_snmp_basic nf_nat_sip nf_nat_proto_gre nf_nat_masquerade_ipv4 nf_nat_irc nf_nat_h323 nf_nat_ftp nf_nat nf_log_ipv4 nf_defrag_ipv6 nf_defrag_ipv4 nf_conntrack_tftp nf_conntrack_snmp nf_conntrack_sip nf_conntrack_rtcache nf_conntrack_proto_gre nf_conntrack_irc nf_conntrack_h323 nf_conntrack_ftp nf_conntrack_broadcast iptable_raw iptable_mangle iptable_filter ipt_ECN ip_tables crc_ccitt ath9k_hw em_nbyte sch_codel sch_prio sch_dsmark act_ipt sch_gred em_meta sch_htb cls_basic sch_netem act_police em_text sch_tbf sch_sfq em_cmp sch_red act_skbedit act_mirred em_u32 cls_u32 cls_tcindex cls_flow cls_route cls_fw sch_hfsc sch_ingress tmp421 hwmon batman_adv libcrc32c crc16 ath10k_pci ath10k_core ath mac80211 cfg80211 compat UDSMARK udsmac i2c_dev tc_classid_mapper(P) filter_group classifier_dns(P) classifier_netblock(P) classifier_bittorrent(P) classifier_rtmp(P) classifier_ssl(P) classifier_content(P) classifier_skype(P) kernel_classifier nf_conntrack xt_set ip_set_list_set ip_set_hash_netport ip_set_hash_netiface ip_set_hash_net ip_set_hash_ipportnet ip_set_hash_ipportip ip_set_hash_ipport ip_set_hash_ip ip_set_bitmap_port ip_set_bitmap_ipmac ip_set_bitmap_ip ip_set nfnetlink ip6t_REJECT nf_reject_ipv6 nf_log_ipv6 nf_log_common ip6table_raw ip6table_mangle ip6table_filter ip6_tables x_tables ifb tun ipv6 arc4 crypto_blkcipher input_polldev gpio_button_hotplug button_hotplug input_core ag71xx crc32c_generic crypto_hash [ 21.700000] Process udhcpc (pid: 1152, threadinfo=8298e000, task=83987070, tls=77051440) [ 21.700000] Stack : 003617ec 80090cb4 80391000 839a8800 00000000 828080a4 0000001c 8340c240 0140c280 8340c2c0 00000000 8340c4c0 832cf480 831aff00 000fcc66 82980100 82951a00 82808090 82980080 828d3420 82808082 83184088 839a8858 82808082 00000d85 00000400 82980100 831aff00 00000000 80094034 00001000 00000000 82808090 828d3000 00000014 8340c580 832cf480 00000001 831aff1c 00000001 ... [ 21.700000] Call Trace: [ 21.700000] [<83183d04>] batadv_v_ogm_orig_get+0x65c/0x738 [batman_adv] [ 21.700000] [ 21.700000] Code: 10400022 00409821 9616000e <8c04000c> 24060020 0c028338 26c50022 1040001c 00408821 [ 22.050000] ---[ end trace 2f89500f9609fb9e ]--- [ 22.050000] Kernel panic - not syncing: Fatal exception in interrupt
b.a.t.m.a.n@lists.open-mesh.org