diff options
author | David S. Miller <davem@davemloft.net> | 2012-05-11 17:57:52 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2012-05-11 17:57:52 -0400 |
commit | 16c788dee1934c2cc4e98692a5a63132d6e07d50 (patch) | |
tree | ebf3db929e39946d44377be7683156fed8f8bc3d | |
parent | 06a4c1c55dbe5d9f7a708e8f1a52fd2ac8e5874f (diff) | |
parent | 35c133a000d54b7e3fe81e8c8e4b8af5878ad6dd (diff) |
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
-rw-r--r-- | net/batman-adv/bat_debugfs.c | 4 | ||||
-rw-r--r-- | net/batman-adv/bat_iv_ogm.c | 176 | ||||
-rw-r--r-- | net/batman-adv/bat_sysfs.c | 100 | ||||
-rw-r--r-- | net/batman-adv/bridge_loop_avoidance.c | 2 | ||||
-rw-r--r-- | net/batman-adv/bridge_loop_avoidance.h | 2 | ||||
-rw-r--r-- | net/batman-adv/gateway_client.c | 6 | ||||
-rw-r--r-- | net/batman-adv/hard-interface.c | 117 | ||||
-rw-r--r-- | net/batman-adv/main.c | 124 | ||||
-rw-r--r-- | net/batman-adv/main.h | 6 | ||||
-rw-r--r-- | net/batman-adv/originator.c | 51 | ||||
-rw-r--r-- | net/batman-adv/originator.h | 7 | ||||
-rw-r--r-- | net/batman-adv/packet.h | 1 | ||||
-rw-r--r-- | net/batman-adv/routing.c | 22 | ||||
-rw-r--r-- | net/batman-adv/routing.h | 4 | ||||
-rw-r--r-- | net/batman-adv/send.c | 2 | ||||
-rw-r--r-- | net/batman-adv/translation-table.c | 2 | ||||
-rw-r--r-- | net/batman-adv/translation-table.h | 2 | ||||
-rw-r--r-- | net/batman-adv/types.h | 17 |
18 files changed, 380 insertions, 265 deletions
diff --git a/net/batman-adv/bat_debugfs.c b/net/batman-adv/bat_debugfs.c index 916380c73ab7..3b588f86d770 100644 --- a/net/batman-adv/bat_debugfs.c +++ b/net/batman-adv/bat_debugfs.c | |||
@@ -83,8 +83,8 @@ int debug_log(struct bat_priv *bat_priv, const char *fmt, ...) | |||
83 | 83 | ||
84 | va_start(args, fmt); | 84 | va_start(args, fmt); |
85 | vscnprintf(tmp_log_buf, sizeof(tmp_log_buf), fmt, args); | 85 | vscnprintf(tmp_log_buf, sizeof(tmp_log_buf), fmt, args); |
86 | fdebug_log(bat_priv->debug_log, "[%10lu] %s", | 86 | fdebug_log(bat_priv->debug_log, "[%10u] %s", |
87 | (jiffies / HZ), tmp_log_buf); | 87 | jiffies_to_msecs(jiffies), tmp_log_buf); |
88 | va_end(args); | 88 | va_end(args); |
89 | 89 | ||
90 | return 0; | 90 | return 0; |
diff --git a/net/batman-adv/bat_iv_ogm.c b/net/batman-adv/bat_iv_ogm.c index 8b2db2e76c7e..abd10c490fd9 100644 --- a/net/batman-adv/bat_iv_ogm.c +++ b/net/batman-adv/bat_iv_ogm.c | |||
@@ -30,6 +30,32 @@ | |||
30 | #include "send.h" | 30 | #include "send.h" |
31 | #include "bat_algo.h" | 31 | #include "bat_algo.h" |
32 | 32 | ||
33 | static struct neigh_node *bat_iv_ogm_neigh_new(struct hard_iface *hard_iface, | ||
34 | const uint8_t *neigh_addr, | ||
35 | struct orig_node *orig_node, | ||
36 | struct orig_node *orig_neigh, | ||
37 | uint32_t seqno) | ||
38 | { | ||
39 | struct neigh_node *neigh_node; | ||
40 | |||
41 | neigh_node = batadv_neigh_node_new(hard_iface, neigh_addr, seqno); | ||
42 | if (!neigh_node) | ||
43 | goto out; | ||
44 | |||
45 | INIT_LIST_HEAD(&neigh_node->bonding_list); | ||
46 | spin_lock_init(&neigh_node->tq_lock); | ||
47 | |||
48 | neigh_node->orig_node = orig_neigh; | ||
49 | neigh_node->if_incoming = hard_iface; | ||
50 | |||
51 | spin_lock_bh(&orig_node->neigh_list_lock); | ||
52 | hlist_add_head_rcu(&neigh_node->list, &orig_node->neigh_list); | ||
53 | spin_unlock_bh(&orig_node->neigh_list_lock); | ||
54 | |||
55 | out: | ||
56 | return neigh_node; | ||
57 | } | ||
58 | |||
33 | static int bat_iv_ogm_iface_enable(struct hard_iface *hard_iface) | 59 | static int bat_iv_ogm_iface_enable(struct hard_iface *hard_iface) |
34 | { | 60 | { |
35 | struct batman_ogm_packet *batman_ogm_packet; | 61 | struct batman_ogm_packet *batman_ogm_packet; |
@@ -67,24 +93,24 @@ static void bat_iv_ogm_iface_disable(struct hard_iface *hard_iface) | |||
67 | hard_iface->packet_buff = NULL; | 93 | hard_iface->packet_buff = NULL; |
68 | } | 94 | } |
69 | 95 | ||
70 | static void bat_iv_ogm_primary_iface_set(struct hard_iface *hard_iface) | 96 | static void bat_iv_ogm_iface_update_mac(struct hard_iface *hard_iface) |
71 | { | 97 | { |
72 | struct batman_ogm_packet *batman_ogm_packet; | 98 | struct batman_ogm_packet *batman_ogm_packet; |
73 | 99 | ||
74 | batman_ogm_packet = (struct batman_ogm_packet *)hard_iface->packet_buff; | 100 | batman_ogm_packet = (struct batman_ogm_packet *)hard_iface->packet_buff; |
75 | batman_ogm_packet->flags = PRIMARIES_FIRST_HOP; | 101 | memcpy(batman_ogm_packet->orig, |
76 | batman_ogm_packet->header.ttl = TTL; | 102 | hard_iface->net_dev->dev_addr, ETH_ALEN); |
103 | memcpy(batman_ogm_packet->prev_sender, | ||
104 | hard_iface->net_dev->dev_addr, ETH_ALEN); | ||
77 | } | 105 | } |
78 | 106 | ||
79 | static void bat_iv_ogm_update_mac(struct hard_iface *hard_iface) | 107 | static void bat_iv_ogm_primary_iface_set(struct hard_iface *hard_iface) |
80 | { | 108 | { |
81 | struct batman_ogm_packet *batman_ogm_packet; | 109 | struct batman_ogm_packet *batman_ogm_packet; |
82 | 110 | ||
83 | batman_ogm_packet = (struct batman_ogm_packet *)hard_iface->packet_buff; | 111 | batman_ogm_packet = (struct batman_ogm_packet *)hard_iface->packet_buff; |
84 | memcpy(batman_ogm_packet->orig, | 112 | batman_ogm_packet->flags = PRIMARIES_FIRST_HOP; |
85 | hard_iface->net_dev->dev_addr, ETH_ALEN); | 113 | batman_ogm_packet->header.ttl = TTL; |
86 | memcpy(batman_ogm_packet->prev_sender, | ||
87 | hard_iface->net_dev->dev_addr, ETH_ALEN); | ||
88 | } | 114 | } |
89 | 115 | ||
90 | /* when do we schedule our own ogm to be sent */ | 116 | /* when do we schedule our own ogm to be sent */ |
@@ -480,11 +506,11 @@ static void bat_iv_ogm_queue_add(struct bat_priv *bat_priv, | |||
480 | static void bat_iv_ogm_forward(struct orig_node *orig_node, | 506 | static void bat_iv_ogm_forward(struct orig_node *orig_node, |
481 | const struct ethhdr *ethhdr, | 507 | const struct ethhdr *ethhdr, |
482 | struct batman_ogm_packet *batman_ogm_packet, | 508 | struct batman_ogm_packet *batman_ogm_packet, |
483 | int directlink, struct hard_iface *if_incoming) | 509 | bool is_single_hop_neigh, |
510 | bool is_from_best_next_hop, | ||
511 | struct hard_iface *if_incoming) | ||
484 | { | 512 | { |
485 | struct bat_priv *bat_priv = netdev_priv(if_incoming->soft_iface); | 513 | struct bat_priv *bat_priv = netdev_priv(if_incoming->soft_iface); |
486 | struct neigh_node *router; | ||
487 | uint8_t in_tq, in_ttl, tq_avg = 0; | ||
488 | uint8_t tt_num_changes; | 514 | uint8_t tt_num_changes; |
489 | 515 | ||
490 | if (batman_ogm_packet->header.ttl <= 1) { | 516 | if (batman_ogm_packet->header.ttl <= 1) { |
@@ -492,48 +518,37 @@ static void bat_iv_ogm_forward(struct orig_node *orig_node, | |||
492 | return; | 518 | return; |
493 | } | 519 | } |
494 | 520 | ||
495 | router = orig_node_get_router(orig_node); | 521 | if (!is_from_best_next_hop) { |
522 | /* Mark the forwarded packet when it is not coming from our | ||
523 | * best next hop. We still need to forward the packet for our | ||
524 | * neighbor link quality detection to work in case the packet | ||
525 | * originated from a single hop neighbor. Otherwise we can | ||
526 | * simply drop the ogm. | ||
527 | */ | ||
528 | if (is_single_hop_neigh) | ||
529 | batman_ogm_packet->flags |= NOT_BEST_NEXT_HOP; | ||
530 | else | ||
531 | return; | ||
532 | } | ||
496 | 533 | ||
497 | in_tq = batman_ogm_packet->tq; | ||
498 | in_ttl = batman_ogm_packet->header.ttl; | ||
499 | tt_num_changes = batman_ogm_packet->tt_num_changes; | 534 | tt_num_changes = batman_ogm_packet->tt_num_changes; |
500 | 535 | ||
501 | batman_ogm_packet->header.ttl--; | 536 | batman_ogm_packet->header.ttl--; |
502 | memcpy(batman_ogm_packet->prev_sender, ethhdr->h_source, ETH_ALEN); | 537 | memcpy(batman_ogm_packet->prev_sender, ethhdr->h_source, ETH_ALEN); |
503 | 538 | ||
504 | /* rebroadcast tq of our best ranking neighbor to ensure the rebroadcast | ||
505 | * of our best tq value */ | ||
506 | if (router && router->tq_avg != 0) { | ||
507 | |||
508 | /* rebroadcast ogm of best ranking neighbor as is */ | ||
509 | if (!compare_eth(router->addr, ethhdr->h_source)) { | ||
510 | batman_ogm_packet->tq = router->tq_avg; | ||
511 | |||
512 | if (router->last_ttl) | ||
513 | batman_ogm_packet->header.ttl = | ||
514 | router->last_ttl - 1; | ||
515 | } | ||
516 | |||
517 | tq_avg = router->tq_avg; | ||
518 | } | ||
519 | |||
520 | if (router) | ||
521 | neigh_node_free_ref(router); | ||
522 | |||
523 | /* apply hop penalty */ | 539 | /* apply hop penalty */ |
524 | batman_ogm_packet->tq = hop_penalty(batman_ogm_packet->tq, bat_priv); | 540 | batman_ogm_packet->tq = hop_penalty(batman_ogm_packet->tq, bat_priv); |
525 | 541 | ||
526 | bat_dbg(DBG_BATMAN, bat_priv, | 542 | bat_dbg(DBG_BATMAN, bat_priv, |
527 | "Forwarding packet: tq_orig: %i, tq_avg: %i, tq_forw: %i, ttl_orig: %i, ttl_forw: %i\n", | 543 | "Forwarding packet: tq: %i, ttl: %i\n", |
528 | in_tq, tq_avg, batman_ogm_packet->tq, in_ttl - 1, | 544 | batman_ogm_packet->tq, batman_ogm_packet->header.ttl); |
529 | batman_ogm_packet->header.ttl); | ||
530 | 545 | ||
531 | batman_ogm_packet->seqno = htonl(batman_ogm_packet->seqno); | 546 | batman_ogm_packet->seqno = htonl(batman_ogm_packet->seqno); |
532 | batman_ogm_packet->tt_crc = htons(batman_ogm_packet->tt_crc); | 547 | batman_ogm_packet->tt_crc = htons(batman_ogm_packet->tt_crc); |
533 | 548 | ||
534 | /* switch of primaries first hop flag when forwarding */ | 549 | /* switch of primaries first hop flag when forwarding */ |
535 | batman_ogm_packet->flags &= ~PRIMARIES_FIRST_HOP; | 550 | batman_ogm_packet->flags &= ~PRIMARIES_FIRST_HOP; |
536 | if (directlink) | 551 | if (is_single_hop_neigh) |
537 | batman_ogm_packet->flags |= DIRECTLINK; | 552 | batman_ogm_packet->flags |= DIRECTLINK; |
538 | else | 553 | else |
539 | batman_ogm_packet->flags &= ~DIRECTLINK; | 554 | batman_ogm_packet->flags &= ~DIRECTLINK; |
@@ -637,8 +652,9 @@ static void bat_iv_ogm_orig_update(struct bat_priv *bat_priv, | |||
637 | if (!orig_tmp) | 652 | if (!orig_tmp) |
638 | goto unlock; | 653 | goto unlock; |
639 | 654 | ||
640 | neigh_node = create_neighbor(orig_node, orig_tmp, | 655 | neigh_node = bat_iv_ogm_neigh_new(if_incoming, ethhdr->h_source, |
641 | ethhdr->h_source, if_incoming); | 656 | orig_node, orig_tmp, |
657 | batman_ogm_packet->seqno); | ||
642 | 658 | ||
643 | orig_node_free_ref(orig_tmp); | 659 | orig_node_free_ref(orig_tmp); |
644 | if (!neigh_node) | 660 | if (!neigh_node) |
@@ -650,7 +666,7 @@ static void bat_iv_ogm_orig_update(struct bat_priv *bat_priv, | |||
650 | rcu_read_unlock(); | 666 | rcu_read_unlock(); |
651 | 667 | ||
652 | orig_node->flags = batman_ogm_packet->flags; | 668 | orig_node->flags = batman_ogm_packet->flags; |
653 | neigh_node->last_valid = jiffies; | 669 | neigh_node->last_seen = jiffies; |
654 | 670 | ||
655 | spin_lock_bh(&neigh_node->tq_lock); | 671 | spin_lock_bh(&neigh_node->tq_lock); |
656 | ring_buffer_set(neigh_node->tq_recv, | 672 | ring_buffer_set(neigh_node->tq_recv, |
@@ -763,19 +779,20 @@ static int bat_iv_ogm_calc_tq(struct orig_node *orig_node, | |||
763 | rcu_read_unlock(); | 779 | rcu_read_unlock(); |
764 | 780 | ||
765 | if (!neigh_node) | 781 | if (!neigh_node) |
766 | neigh_node = create_neighbor(orig_neigh_node, | 782 | neigh_node = bat_iv_ogm_neigh_new(if_incoming, |
767 | orig_neigh_node, | 783 | orig_neigh_node->orig, |
768 | orig_neigh_node->orig, | 784 | orig_neigh_node, |
769 | if_incoming); | 785 | orig_neigh_node, |
786 | batman_ogm_packet->seqno); | ||
770 | 787 | ||
771 | if (!neigh_node) | 788 | if (!neigh_node) |
772 | goto out; | 789 | goto out; |
773 | 790 | ||
774 | /* if orig_node is direct neighbor update neigh_node last_valid */ | 791 | /* if orig_node is direct neighbor update neigh_node last_seen */ |
775 | if (orig_node == orig_neigh_node) | 792 | if (orig_node == orig_neigh_node) |
776 | neigh_node->last_valid = jiffies; | 793 | neigh_node->last_seen = jiffies; |
777 | 794 | ||
778 | orig_node->last_valid = jiffies; | 795 | orig_node->last_seen = jiffies; |
779 | 796 | ||
780 | /* find packet count of corresponding one hop neighbor */ | 797 | /* find packet count of corresponding one hop neighbor */ |
781 | spin_lock_bh(&orig_node->ogm_cnt_lock); | 798 | spin_lock_bh(&orig_node->ogm_cnt_lock); |
@@ -918,7 +935,9 @@ static void bat_iv_ogm_process(const struct ethhdr *ethhdr, | |||
918 | struct neigh_node *orig_neigh_router = NULL; | 935 | struct neigh_node *orig_neigh_router = NULL; |
919 | int has_directlink_flag; | 936 | int has_directlink_flag; |
920 | int is_my_addr = 0, is_my_orig = 0, is_my_oldorig = 0; | 937 | int is_my_addr = 0, is_my_orig = 0, is_my_oldorig = 0; |
921 | int is_broadcast = 0, is_bidirectional, is_single_hop_neigh; | 938 | int is_broadcast = 0, is_bidirectional; |
939 | bool is_single_hop_neigh = false; | ||
940 | bool is_from_best_next_hop = false; | ||
922 | int is_duplicate; | 941 | int is_duplicate; |
923 | uint32_t if_incoming_seqno; | 942 | uint32_t if_incoming_seqno; |
924 | 943 | ||
@@ -942,8 +961,8 @@ static void bat_iv_ogm_process(const struct ethhdr *ethhdr, | |||
942 | 961 | ||
943 | has_directlink_flag = (batman_ogm_packet->flags & DIRECTLINK ? 1 : 0); | 962 | has_directlink_flag = (batman_ogm_packet->flags & DIRECTLINK ? 1 : 0); |
944 | 963 | ||
945 | is_single_hop_neigh = (compare_eth(ethhdr->h_source, | 964 | if (compare_eth(ethhdr->h_source, batman_ogm_packet->orig)) |
946 | batman_ogm_packet->orig) ? 1 : 0); | 965 | is_single_hop_neigh = true; |
947 | 966 | ||
948 | bat_dbg(DBG_BATMAN, bat_priv, | 967 | bat_dbg(DBG_BATMAN, bat_priv, |
949 | "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", | 968 | "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", |
@@ -1040,6 +1059,13 @@ static void bat_iv_ogm_process(const struct ethhdr *ethhdr, | |||
1040 | return; | 1059 | return; |
1041 | } | 1060 | } |
1042 | 1061 | ||
1062 | if (batman_ogm_packet->flags & NOT_BEST_NEXT_HOP) { | ||
1063 | bat_dbg(DBG_BATMAN, bat_priv, | ||
1064 | "Drop packet: ignoring all packets not forwarded from the best next hop (sender: %pM)\n", | ||
1065 | ethhdr->h_source); | ||
1066 | return; | ||
1067 | } | ||
1068 | |||
1043 | orig_node = get_orig_node(bat_priv, batman_ogm_packet->orig); | 1069 | orig_node = get_orig_node(bat_priv, batman_ogm_packet->orig); |
1044 | if (!orig_node) | 1070 | if (!orig_node) |
1045 | return; | 1071 | return; |
@@ -1064,6 +1090,10 @@ static void bat_iv_ogm_process(const struct ethhdr *ethhdr, | |||
1064 | if (router) | 1090 | if (router) |
1065 | router_router = orig_node_get_router(router->orig_node); | 1091 | router_router = orig_node_get_router(router->orig_node); |
1066 | 1092 | ||
1093 | if ((router && router->tq_avg != 0) && | ||
1094 | (compare_eth(router->addr, ethhdr->h_source))) | ||
1095 | is_from_best_next_hop = true; | ||
1096 | |||
1067 | /* avoid temporary routing loops */ | 1097 | /* avoid temporary routing loops */ |
1068 | if (router && router_router && | 1098 | if (router && router_router && |
1069 | (compare_eth(router->addr, batman_ogm_packet->prev_sender)) && | 1099 | (compare_eth(router->addr, batman_ogm_packet->prev_sender)) && |
@@ -1114,7 +1144,8 @@ static void bat_iv_ogm_process(const struct ethhdr *ethhdr, | |||
1114 | 1144 | ||
1115 | /* mark direct link on incoming interface */ | 1145 | /* mark direct link on incoming interface */ |
1116 | bat_iv_ogm_forward(orig_node, ethhdr, batman_ogm_packet, | 1146 | bat_iv_ogm_forward(orig_node, ethhdr, batman_ogm_packet, |
1117 | 1, if_incoming); | 1147 | is_single_hop_neigh, is_from_best_next_hop, |
1148 | if_incoming); | ||
1118 | 1149 | ||
1119 | bat_dbg(DBG_BATMAN, bat_priv, | 1150 | bat_dbg(DBG_BATMAN, bat_priv, |
1120 | "Forwarding packet: rebroadcast neighbor packet with direct link flag\n"); | 1151 | "Forwarding packet: rebroadcast neighbor packet with direct link flag\n"); |
@@ -1137,7 +1168,8 @@ static void bat_iv_ogm_process(const struct ethhdr *ethhdr, | |||
1137 | bat_dbg(DBG_BATMAN, bat_priv, | 1168 | bat_dbg(DBG_BATMAN, bat_priv, |
1138 | "Forwarding packet: rebroadcast originator packet\n"); | 1169 | "Forwarding packet: rebroadcast originator packet\n"); |
1139 | bat_iv_ogm_forward(orig_node, ethhdr, batman_ogm_packet, | 1170 | bat_iv_ogm_forward(orig_node, ethhdr, batman_ogm_packet, |
1140 | 0, if_incoming); | 1171 | is_single_hop_neigh, is_from_best_next_hop, |
1172 | if_incoming); | ||
1141 | 1173 | ||
1142 | out_neigh: | 1174 | out_neigh: |
1143 | if ((orig_neigh_node) && (!is_single_hop_neigh)) | 1175 | if ((orig_neigh_node) && (!is_single_hop_neigh)) |
@@ -1153,13 +1185,25 @@ out: | |||
1153 | orig_node_free_ref(orig_node); | 1185 | orig_node_free_ref(orig_node); |
1154 | } | 1186 | } |
1155 | 1187 | ||
1156 | static void bat_iv_ogm_receive(struct hard_iface *if_incoming, | 1188 | static int bat_iv_ogm_receive(struct sk_buff *skb, |
1157 | struct sk_buff *skb) | 1189 | struct hard_iface *if_incoming) |
1158 | { | 1190 | { |
1191 | struct bat_priv *bat_priv = netdev_priv(if_incoming->soft_iface); | ||
1159 | struct batman_ogm_packet *batman_ogm_packet; | 1192 | struct batman_ogm_packet *batman_ogm_packet; |
1160 | struct ethhdr *ethhdr; | 1193 | struct ethhdr *ethhdr; |
1161 | int buff_pos = 0, packet_len; | 1194 | int buff_pos = 0, packet_len; |
1162 | unsigned char *tt_buff, *packet_buff; | 1195 | unsigned char *tt_buff, *packet_buff; |
1196 | bool ret; | ||
1197 | |||
1198 | ret = check_management_packet(skb, if_incoming, BATMAN_OGM_HLEN); | ||
1199 | if (!ret) | ||
1200 | return NET_RX_DROP; | ||
1201 | |||
1202 | /* did we receive a B.A.T.M.A.N. IV OGM packet on an interface | ||
1203 | * that does not have B.A.T.M.A.N. IV enabled ? | ||
1204 | */ | ||
1205 | if (bat_priv->bat_algo_ops->bat_ogm_emit != bat_iv_ogm_emit) | ||
1206 | return NET_RX_DROP; | ||
1163 | 1207 | ||
1164 | packet_len = skb_headlen(skb); | 1208 | packet_len = skb_headlen(skb); |
1165 | ethhdr = (struct ethhdr *)skb_mac_header(skb); | 1209 | ethhdr = (struct ethhdr *)skb_mac_header(skb); |
@@ -1185,20 +1229,38 @@ static void bat_iv_ogm_receive(struct hard_iface *if_incoming, | |||
1185 | (packet_buff + buff_pos); | 1229 | (packet_buff + buff_pos); |
1186 | } while (bat_iv_ogm_aggr_packet(buff_pos, packet_len, | 1230 | } while (bat_iv_ogm_aggr_packet(buff_pos, packet_len, |
1187 | batman_ogm_packet->tt_num_changes)); | 1231 | batman_ogm_packet->tt_num_changes)); |
1232 | |||
1233 | kfree_skb(skb); | ||
1234 | return NET_RX_SUCCESS; | ||
1188 | } | 1235 | } |
1189 | 1236 | ||
1190 | static struct bat_algo_ops batman_iv __read_mostly = { | 1237 | static struct bat_algo_ops batman_iv __read_mostly = { |
1191 | .name = "BATMAN IV", | 1238 | .name = "BATMAN IV", |
1192 | .bat_iface_enable = bat_iv_ogm_iface_enable, | 1239 | .bat_iface_enable = bat_iv_ogm_iface_enable, |
1193 | .bat_iface_disable = bat_iv_ogm_iface_disable, | 1240 | .bat_iface_disable = bat_iv_ogm_iface_disable, |
1241 | .bat_iface_update_mac = bat_iv_ogm_iface_update_mac, | ||
1194 | .bat_primary_iface_set = bat_iv_ogm_primary_iface_set, | 1242 | .bat_primary_iface_set = bat_iv_ogm_primary_iface_set, |
1195 | .bat_ogm_update_mac = bat_iv_ogm_update_mac, | ||
1196 | .bat_ogm_schedule = bat_iv_ogm_schedule, | 1243 | .bat_ogm_schedule = bat_iv_ogm_schedule, |
1197 | .bat_ogm_emit = bat_iv_ogm_emit, | 1244 | .bat_ogm_emit = bat_iv_ogm_emit, |
1198 | .bat_ogm_receive = bat_iv_ogm_receive, | ||
1199 | }; | 1245 | }; |
1200 | 1246 | ||
1201 | int __init bat_iv_init(void) | 1247 | int __init bat_iv_init(void) |
1202 | { | 1248 | { |
1203 | return bat_algo_register(&batman_iv); | 1249 | int ret; |
1250 | |||
1251 | /* batman originator packet */ | ||
1252 | ret = recv_handler_register(BAT_IV_OGM, bat_iv_ogm_receive); | ||
1253 | if (ret < 0) | ||
1254 | goto out; | ||
1255 | |||
1256 | ret = bat_algo_register(&batman_iv); | ||
1257 | if (ret < 0) | ||
1258 | goto handler_unregister; | ||
1259 | |||
1260 | goto out; | ||
1261 | |||
1262 | handler_unregister: | ||
1263 | recv_handler_unregister(BAT_IV_OGM); | ||
1264 | out: | ||
1265 | return ret; | ||
1204 | } | 1266 | } |
diff --git a/net/batman-adv/bat_sysfs.c b/net/batman-adv/bat_sysfs.c index 2c816883ca13..5bc7b66d32dc 100644 --- a/net/batman-adv/bat_sysfs.c +++ b/net/batman-adv/bat_sysfs.c | |||
@@ -63,7 +63,7 @@ struct bat_attribute bat_attr_##_name = { \ | |||
63 | .store = _store, \ | 63 | .store = _store, \ |
64 | }; | 64 | }; |
65 | 65 | ||
66 | #define BAT_ATTR_STORE_BOOL(_name, _post_func) \ | 66 | #define BAT_ATTR_SIF_STORE_BOOL(_name, _post_func) \ |
67 | ssize_t store_##_name(struct kobject *kobj, struct attribute *attr, \ | 67 | ssize_t store_##_name(struct kobject *kobj, struct attribute *attr, \ |
68 | char *buff, size_t count) \ | 68 | char *buff, size_t count) \ |
69 | { \ | 69 | { \ |
@@ -73,9 +73,9 @@ ssize_t store_##_name(struct kobject *kobj, struct attribute *attr, \ | |||
73 | &bat_priv->_name, net_dev); \ | 73 | &bat_priv->_name, net_dev); \ |
74 | } | 74 | } |
75 | 75 | ||
76 | #define BAT_ATTR_SHOW_BOOL(_name) \ | 76 | #define BAT_ATTR_SIF_SHOW_BOOL(_name) \ |
77 | ssize_t show_##_name(struct kobject *kobj, struct attribute *attr, \ | 77 | ssize_t show_##_name(struct kobject *kobj, \ |
78 | char *buff) \ | 78 | struct attribute *attr, char *buff) \ |
79 | { \ | 79 | { \ |
80 | struct bat_priv *bat_priv = kobj_to_batpriv(kobj); \ | 80 | struct bat_priv *bat_priv = kobj_to_batpriv(kobj); \ |
81 | return sprintf(buff, "%s\n", \ | 81 | return sprintf(buff, "%s\n", \ |
@@ -83,16 +83,17 @@ ssize_t show_##_name(struct kobject *kobj, struct attribute *attr, \ | |||
83 | "disabled" : "enabled"); \ | 83 | "disabled" : "enabled"); \ |
84 | } \ | 84 | } \ |
85 | 85 | ||
86 | /* Use this, if you are going to turn a [name] in bat_priv on or off */ | 86 | /* Use this, if you are going to turn a [name] in the soft-interface |
87 | #define BAT_ATTR_BOOL(_name, _mode, _post_func) \ | 87 | * (bat_priv) on or off */ |
88 | static BAT_ATTR_STORE_BOOL(_name, _post_func) \ | 88 | #define BAT_ATTR_SIF_BOOL(_name, _mode, _post_func) \ |
89 | static BAT_ATTR_SHOW_BOOL(_name) \ | 89 | static BAT_ATTR_SIF_STORE_BOOL(_name, _post_func) \ |
90 | static BAT_ATTR_SIF_SHOW_BOOL(_name) \ | ||
90 | static BAT_ATTR(_name, _mode, show_##_name, store_##_name) | 91 | static BAT_ATTR(_name, _mode, show_##_name, store_##_name) |
91 | 92 | ||
92 | 93 | ||
93 | #define BAT_ATTR_STORE_UINT(_name, _min, _max, _post_func) \ | 94 | #define BAT_ATTR_SIF_STORE_UINT(_name, _min, _max, _post_func) \ |
94 | ssize_t store_##_name(struct kobject *kobj, struct attribute *attr, \ | 95 | ssize_t store_##_name(struct kobject *kobj, struct attribute *attr, \ |
95 | char *buff, size_t count) \ | 96 | char *buff, size_t count) \ |
96 | { \ | 97 | { \ |
97 | struct net_device *net_dev = kobj_to_netdev(kobj); \ | 98 | struct net_device *net_dev = kobj_to_netdev(kobj); \ |
98 | struct bat_priv *bat_priv = netdev_priv(net_dev); \ | 99 | struct bat_priv *bat_priv = netdev_priv(net_dev); \ |
@@ -100,19 +101,62 @@ ssize_t store_##_name(struct kobject *kobj, struct attribute *attr, \ | |||
100 | attr, &bat_priv->_name, net_dev); \ | 101 | attr, &bat_priv->_name, net_dev); \ |
101 | } | 102 | } |
102 | 103 | ||
103 | #define BAT_ATTR_SHOW_UINT(_name) \ | 104 | #define BAT_ATTR_SIF_SHOW_UINT(_name) \ |
104 | ssize_t show_##_name(struct kobject *kobj, struct attribute *attr, \ | 105 | ssize_t show_##_name(struct kobject *kobj, \ |
105 | char *buff) \ | 106 | struct attribute *attr, char *buff) \ |
106 | { \ | 107 | { \ |
107 | struct bat_priv *bat_priv = kobj_to_batpriv(kobj); \ | 108 | struct bat_priv *bat_priv = kobj_to_batpriv(kobj); \ |
108 | return sprintf(buff, "%i\n", atomic_read(&bat_priv->_name)); \ | 109 | return sprintf(buff, "%i\n", atomic_read(&bat_priv->_name)); \ |
109 | } \ | 110 | } \ |
110 | 111 | ||
111 | /* Use this, if you are going to set [name] in bat_priv to unsigned integer | 112 | /* Use this, if you are going to set [name] in the soft-interface |
112 | * values only */ | 113 | * (bat_priv) to an unsigned integer value */ |
113 | #define BAT_ATTR_UINT(_name, _mode, _min, _max, _post_func) \ | 114 | #define BAT_ATTR_SIF_UINT(_name, _mode, _min, _max, _post_func) \ |
114 | static BAT_ATTR_STORE_UINT(_name, _min, _max, _post_func) \ | 115 | static BAT_ATTR_SIF_STORE_UINT(_name, _min, _max, _post_func) \ |
115 | static BAT_ATTR_SHOW_UINT(_name) \ | 116 | static BAT_ATTR_SIF_SHOW_UINT(_name) \ |
117 | static BAT_ATTR(_name, _mode, show_##_name, store_##_name) | ||
118 | |||
119 | |||
120 | #define BAT_ATTR_HIF_STORE_UINT(_name, _min, _max, _post_func) \ | ||
121 | ssize_t store_##_name(struct kobject *kobj, struct attribute *attr, \ | ||
122 | char *buff, size_t count) \ | ||
123 | { \ | ||
124 | struct net_device *net_dev = kobj_to_netdev(kobj); \ | ||
125 | struct hard_iface *hard_iface = hardif_get_by_netdev(net_dev); \ | ||
126 | ssize_t length; \ | ||
127 | \ | ||
128 | if (!hard_iface) \ | ||
129 | return 0; \ | ||
130 | \ | ||
131 | length = __store_uint_attr(buff, count, _min, _max, _post_func, \ | ||
132 | attr, &hard_iface->_name, net_dev); \ | ||
133 | \ | ||
134 | hardif_free_ref(hard_iface); \ | ||
135 | return length; \ | ||
136 | } | ||
137 | |||
138 | #define BAT_ATTR_HIF_SHOW_UINT(_name) \ | ||
139 | ssize_t show_##_name(struct kobject *kobj, \ | ||
140 | struct attribute *attr, char *buff) \ | ||
141 | { \ | ||
142 | struct net_device *net_dev = kobj_to_netdev(kobj); \ | ||
143 | struct hard_iface *hard_iface = hardif_get_by_netdev(net_dev); \ | ||
144 | ssize_t length; \ | ||
145 | \ | ||
146 | if (!hard_iface) \ | ||
147 | return 0; \ | ||
148 | \ | ||
149 | length = sprintf(buff, "%i\n", atomic_read(&hard_iface->_name));\ | ||
150 | \ | ||
151 | hardif_free_ref(hard_iface); \ | ||
152 | return length; \ | ||
153 | } | ||
154 | |||
155 | /* Use this, if you are going to set [name] in hard_iface to an | ||
156 | * unsigned integer value*/ | ||
157 | #define BAT_ATTR_HIF_UINT(_name, _mode, _min, _max, _post_func) \ | ||
158 | static BAT_ATTR_HIF_STORE_UINT(_name, _min, _max, _post_func) \ | ||
159 | static BAT_ATTR_HIF_SHOW_UINT(_name) \ | ||
116 | static BAT_ATTR(_name, _mode, show_##_name, store_##_name) | 160 | static BAT_ATTR(_name, _mode, show_##_name, store_##_name) |
117 | 161 | ||
118 | 162 | ||
@@ -384,24 +428,24 @@ static ssize_t store_gw_bwidth(struct kobject *kobj, struct attribute *attr, | |||
384 | return gw_bandwidth_set(net_dev, buff, count); | 428 | return gw_bandwidth_set(net_dev, buff, count); |
385 | } | 429 | } |
386 | 430 | ||
387 | BAT_ATTR_BOOL(aggregated_ogms, S_IRUGO | S_IWUSR, NULL); | 431 | BAT_ATTR_SIF_BOOL(aggregated_ogms, S_IRUGO | S_IWUSR, NULL); |
388 | BAT_ATTR_BOOL(bonding, S_IRUGO | S_IWUSR, NULL); | 432 | BAT_ATTR_SIF_BOOL(bonding, S_IRUGO | S_IWUSR, NULL); |
389 | #ifdef CONFIG_BATMAN_ADV_BLA | 433 | #ifdef CONFIG_BATMAN_ADV_BLA |
390 | BAT_ATTR_BOOL(bridge_loop_avoidance, S_IRUGO | S_IWUSR, NULL); | 434 | BAT_ATTR_SIF_BOOL(bridge_loop_avoidance, S_IRUGO | S_IWUSR, NULL); |
391 | #endif | 435 | #endif |
392 | BAT_ATTR_BOOL(fragmentation, S_IRUGO | S_IWUSR, update_min_mtu); | 436 | BAT_ATTR_SIF_BOOL(fragmentation, S_IRUGO | S_IWUSR, update_min_mtu); |
393 | BAT_ATTR_BOOL(ap_isolation, S_IRUGO | S_IWUSR, NULL); | 437 | BAT_ATTR_SIF_BOOL(ap_isolation, S_IRUGO | S_IWUSR, NULL); |
394 | static BAT_ATTR(vis_mode, S_IRUGO | S_IWUSR, show_vis_mode, store_vis_mode); | 438 | static BAT_ATTR(vis_mode, S_IRUGO | S_IWUSR, show_vis_mode, store_vis_mode); |
395 | static BAT_ATTR(routing_algo, S_IRUGO, show_bat_algo, NULL); | 439 | static BAT_ATTR(routing_algo, S_IRUGO, show_bat_algo, NULL); |
396 | static BAT_ATTR(gw_mode, S_IRUGO | S_IWUSR, show_gw_mode, store_gw_mode); | 440 | static BAT_ATTR(gw_mode, S_IRUGO | S_IWUSR, show_gw_mode, store_gw_mode); |
397 | BAT_ATTR_UINT(orig_interval, S_IRUGO | S_IWUSR, 2 * JITTER, INT_MAX, NULL); | 441 | BAT_ATTR_SIF_UINT(orig_interval, S_IRUGO | S_IWUSR, 2 * JITTER, INT_MAX, NULL); |
398 | BAT_ATTR_UINT(hop_penalty, S_IRUGO | S_IWUSR, 0, TQ_MAX_VALUE, NULL); | 442 | BAT_ATTR_SIF_UINT(hop_penalty, S_IRUGO | S_IWUSR, 0, TQ_MAX_VALUE, NULL); |
399 | BAT_ATTR_UINT(gw_sel_class, S_IRUGO | S_IWUSR, 1, TQ_MAX_VALUE, | 443 | BAT_ATTR_SIF_UINT(gw_sel_class, S_IRUGO | S_IWUSR, 1, TQ_MAX_VALUE, |
400 | post_gw_deselect); | 444 | post_gw_deselect); |
401 | static BAT_ATTR(gw_bandwidth, S_IRUGO | S_IWUSR, show_gw_bwidth, | 445 | static BAT_ATTR(gw_bandwidth, S_IRUGO | S_IWUSR, show_gw_bwidth, |
402 | store_gw_bwidth); | 446 | store_gw_bwidth); |
403 | #ifdef CONFIG_BATMAN_ADV_DEBUG | 447 | #ifdef CONFIG_BATMAN_ADV_DEBUG |
404 | BAT_ATTR_UINT(log_level, S_IRUGO | S_IWUSR, 0, 15, NULL); | 448 | BAT_ATTR_SIF_UINT(log_level, S_IRUGO | S_IWUSR, 0, 15, NULL); |
405 | #endif | 449 | #endif |
406 | 450 | ||
407 | static struct bat_attribute *mesh_attrs[] = { | 451 | static struct bat_attribute *mesh_attrs[] = { |
diff --git a/net/batman-adv/bridge_loop_avoidance.c b/net/batman-adv/bridge_loop_avoidance.c index ad394c6496cc..8bf97515a77d 100644 --- a/net/batman-adv/bridge_loop_avoidance.c +++ b/net/batman-adv/bridge_loop_avoidance.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) 2011 B.A.T.M.A.N. contributors: | 2 | * Copyright (C) 2011-2012 B.A.T.M.A.N. contributors: |
3 | * | 3 | * |
4 | * Simon Wunderlich | 4 | * Simon Wunderlich |
5 | * | 5 | * |
diff --git a/net/batman-adv/bridge_loop_avoidance.h b/net/batman-adv/bridge_loop_avoidance.h index 4a8e4fc766bc..e39f93acc28f 100644 --- a/net/batman-adv/bridge_loop_avoidance.h +++ b/net/batman-adv/bridge_loop_avoidance.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) 2011 B.A.T.M.A.N. contributors: | 2 | * Copyright (C) 2011-2012 B.A.T.M.A.N. contributors: |
3 | * | 3 | * |
4 | * Simon Wunderlich | 4 | * Simon Wunderlich |
5 | * | 5 | * |
diff --git a/net/batman-adv/gateway_client.c b/net/batman-adv/gateway_client.c index 6f9b9b78f77d..47f7186dcefc 100644 --- a/net/batman-adv/gateway_client.c +++ b/net/batman-adv/gateway_client.c | |||
@@ -558,10 +558,10 @@ static bool is_type_dhcprequest(struct sk_buff *skb, int header_len) | |||
558 | p++; | 558 | p++; |
559 | 559 | ||
560 | /* ...and then we jump over the data */ | 560 | /* ...and then we jump over the data */ |
561 | if (pkt_len < *p) | 561 | if (pkt_len < 1 + (*p)) |
562 | goto out; | 562 | goto out; |
563 | pkt_len -= *p; | 563 | pkt_len -= 1 + (*p); |
564 | p += (*p); | 564 | p += 1 + (*p); |
565 | } | 565 | } |
566 | } | 566 | } |
567 | out: | 567 | out: |
diff --git a/net/batman-adv/hard-interface.c b/net/batman-adv/hard-interface.c index 47c79d724ba3..0b84bb1b62c4 100644 --- a/net/batman-adv/hard-interface.c +++ b/net/batman-adv/hard-interface.c | |||
@@ -32,12 +32,6 @@ | |||
32 | 32 | ||
33 | #include <linux/if_arp.h> | 33 | #include <linux/if_arp.h> |
34 | 34 | ||
35 | |||
36 | static int batman_skb_recv(struct sk_buff *skb, | ||
37 | struct net_device *dev, | ||
38 | struct packet_type *ptype, | ||
39 | struct net_device *orig_dev); | ||
40 | |||
41 | void hardif_free_rcu(struct rcu_head *rcu) | 35 | void hardif_free_rcu(struct rcu_head *rcu) |
42 | { | 36 | { |
43 | struct hard_iface *hard_iface; | 37 | struct hard_iface *hard_iface; |
@@ -234,7 +228,7 @@ static void hardif_activate_interface(struct hard_iface *hard_iface) | |||
234 | 228 | ||
235 | bat_priv = netdev_priv(hard_iface->soft_iface); | 229 | bat_priv = netdev_priv(hard_iface->soft_iface); |
236 | 230 | ||
237 | bat_priv->bat_algo_ops->bat_ogm_update_mac(hard_iface); | 231 | bat_priv->bat_algo_ops->bat_iface_update_mac(hard_iface); |
238 | hard_iface->if_status = IF_TO_BE_ACTIVATED; | 232 | hard_iface->if_status = IF_TO_BE_ACTIVATED; |
239 | 233 | ||
240 | /** | 234 | /** |
@@ -530,7 +524,7 @@ static int hard_if_event(struct notifier_block *this, | |||
530 | check_known_mac_addr(hard_iface->net_dev); | 524 | check_known_mac_addr(hard_iface->net_dev); |
531 | 525 | ||
532 | bat_priv = netdev_priv(hard_iface->soft_iface); | 526 | bat_priv = netdev_priv(hard_iface->soft_iface); |
533 | bat_priv->bat_algo_ops->bat_ogm_update_mac(hard_iface); | 527 | bat_priv->bat_algo_ops->bat_iface_update_mac(hard_iface); |
534 | 528 | ||
535 | primary_if = primary_if_get_selected(bat_priv); | 529 | primary_if = primary_if_get_selected(bat_priv); |
536 | if (!primary_if) | 530 | if (!primary_if) |
@@ -551,113 +545,6 @@ out: | |||
551 | return NOTIFY_DONE; | 545 | return NOTIFY_DONE; |
552 | } | 546 | } |
553 | 547 | ||
554 | /* incoming packets with the batman ethertype received on any active hard | ||
555 | * interface */ | ||
556 | static int batman_skb_recv(struct sk_buff *skb, struct net_device *dev, | ||
557 | struct packet_type *ptype, | ||
558 | struct net_device *orig_dev) | ||
559 | { | ||
560 | struct bat_priv *bat_priv; | ||
561 | struct batman_ogm_packet *batman_ogm_packet; | ||
562 | struct hard_iface *hard_iface; | ||
563 | int ret; | ||
564 | |||
565 | hard_iface = container_of(ptype, struct hard_iface, batman_adv_ptype); | ||
566 | skb = skb_share_check(skb, GFP_ATOMIC); | ||
567 | |||
568 | /* skb was released by skb_share_check() */ | ||
569 | if (!skb) | ||
570 | goto err_out; | ||
571 | |||
572 | /* packet should hold at least type and version */ | ||
573 | if (unlikely(!pskb_may_pull(skb, 2))) | ||
574 | goto err_free; | ||
575 | |||
576 | /* expect a valid ethernet header here. */ | ||
577 | if (unlikely(skb->mac_len != ETH_HLEN || !skb_mac_header(skb))) | ||
578 | goto err_free; | ||
579 | |||
580 | if (!hard_iface->soft_iface) | ||
581 | goto err_free; | ||
582 | |||
583 | bat_priv = netdev_priv(hard_iface->soft_iface); | ||
584 | |||
585 | if (atomic_read(&bat_priv->mesh_state) != MESH_ACTIVE) | ||
586 | goto err_free; | ||
587 | |||
588 | /* discard frames on not active interfaces */ | ||
589 | if (hard_iface->if_status != IF_ACTIVE) | ||
590 | goto err_free; | ||
591 | |||
592 | batman_ogm_packet = (struct batman_ogm_packet *)skb->data; | ||
593 | |||
594 | if (batman_ogm_packet->header.version != COMPAT_VERSION) { | ||
595 | bat_dbg(DBG_BATMAN, bat_priv, | ||
596 | "Drop packet: incompatible batman version (%i)\n", | ||
597 | batman_ogm_packet->header.version); | ||
598 | goto err_free; | ||
599 | } | ||
600 | |||
601 | /* all receive handlers return whether they received or reused | ||
602 | * the supplied skb. if not, we have to free the skb. */ | ||
603 | |||
604 | switch (batman_ogm_packet->header.packet_type) { | ||
605 | /* batman originator packet */ | ||
606 | case BAT_IV_OGM: | ||
607 | ret = recv_bat_ogm_packet(skb, hard_iface); | ||
608 | break; | ||
609 | |||
610 | /* batman icmp packet */ | ||
611 | case BAT_ICMP: | ||
612 | ret = recv_icmp_packet(skb, hard_iface); | ||
613 | break; | ||
614 | |||
615 | /* unicast packet */ | ||
616 | case BAT_UNICAST: | ||
617 | ret = recv_unicast_packet(skb, hard_iface); | ||
618 | break; | ||
619 | |||
620 | /* fragmented unicast packet */ | ||
621 | case BAT_UNICAST_FRAG: | ||
622 | ret = recv_ucast_frag_packet(skb, hard_iface); | ||
623 | break; | ||
624 | |||
625 | /* broadcast packet */ | ||
626 | case BAT_BCAST: | ||
627 | ret = recv_bcast_packet(skb, hard_iface); | ||
628 | break; | ||
629 | |||
630 | /* vis packet */ | ||
631 | case BAT_VIS: | ||
632 | ret = recv_vis_packet(skb, hard_iface); | ||
633 | break; | ||
634 | /* Translation table query (request or response) */ | ||
635 | case BAT_TT_QUERY: | ||
636 | ret = recv_tt_query(skb, hard_iface); | ||
637 | break; | ||
638 | /* Roaming advertisement */ | ||
639 | case BAT_ROAM_ADV: | ||
640 | ret = recv_roam_adv(skb, hard_iface); | ||
641 | break; | ||
642 | default: | ||
643 | ret = NET_RX_DROP; | ||
644 | } | ||
645 | |||
646 | if (ret == NET_RX_DROP) | ||
647 | kfree_skb(skb); | ||
648 | |||
649 | /* return NET_RX_SUCCESS in any case as we | ||
650 | * most probably dropped the packet for | ||
651 | * routing-logical reasons. */ | ||
652 | |||
653 | return NET_RX_SUCCESS; | ||
654 | |||
655 | err_free: | ||
656 | kfree_skb(skb); | ||
657 | err_out: | ||
658 | return NET_RX_DROP; | ||
659 | } | ||
660 | |||
661 | /* This function returns true if the interface represented by ifindex is a | 548 | /* This function returns true if the interface represented by ifindex is a |
662 | * 802.11 wireless device */ | 549 | * 802.11 wireless device */ |
663 | bool is_wifi_iface(int ifindex) | 550 | bool is_wifi_iface(int ifindex) |
diff --git a/net/batman-adv/main.c b/net/batman-adv/main.c index 791327219531..083a2993efe4 100644 --- a/net/batman-adv/main.c +++ b/net/batman-adv/main.c | |||
@@ -39,6 +39,7 @@ | |||
39 | /* List manipulations on hardif_list have to be rtnl_lock()'ed, | 39 | /* List manipulations on hardif_list have to be rtnl_lock()'ed, |
40 | * list traversals just rcu-locked */ | 40 | * list traversals just rcu-locked */ |
41 | struct list_head hardif_list; | 41 | struct list_head hardif_list; |
42 | static int (*recv_packet_handler[256])(struct sk_buff *, struct hard_iface *); | ||
42 | char bat_routing_algo[20] = "BATMAN IV"; | 43 | char bat_routing_algo[20] = "BATMAN IV"; |
43 | static struct hlist_head bat_algo_list; | 44 | static struct hlist_head bat_algo_list; |
44 | 45 | ||
@@ -46,11 +47,15 @@ unsigned char broadcast_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; | |||
46 | 47 | ||
47 | struct workqueue_struct *bat_event_workqueue; | 48 | struct workqueue_struct *bat_event_workqueue; |
48 | 49 | ||
50 | static void recv_handler_init(void); | ||
51 | |||
49 | static int __init batman_init(void) | 52 | static int __init batman_init(void) |
50 | { | 53 | { |
51 | INIT_LIST_HEAD(&hardif_list); | 54 | INIT_LIST_HEAD(&hardif_list); |
52 | INIT_HLIST_HEAD(&bat_algo_list); | 55 | INIT_HLIST_HEAD(&bat_algo_list); |
53 | 56 | ||
57 | recv_handler_init(); | ||
58 | |||
54 | bat_iv_init(); | 59 | bat_iv_init(); |
55 | 60 | ||
56 | /* the name should not be longer than 10 chars - see | 61 | /* the name should not be longer than 10 chars - see |
@@ -179,6 +184,120 @@ int is_my_mac(const uint8_t *addr) | |||
179 | return 0; | 184 | return 0; |
180 | } | 185 | } |
181 | 186 | ||
187 | static int recv_unhandled_packet(struct sk_buff *skb, | ||
188 | struct hard_iface *recv_if) | ||
189 | { | ||
190 | return NET_RX_DROP; | ||
191 | } | ||
192 | |||
193 | /* incoming packets with the batman ethertype received on any active hard | ||
194 | * interface | ||
195 | */ | ||
196 | int batman_skb_recv(struct sk_buff *skb, struct net_device *dev, | ||
197 | struct packet_type *ptype, struct net_device *orig_dev) | ||
198 | { | ||
199 | struct bat_priv *bat_priv; | ||
200 | struct batman_ogm_packet *batman_ogm_packet; | ||
201 | struct hard_iface *hard_iface; | ||
202 | uint8_t idx; | ||
203 | int ret; | ||
204 | |||
205 | hard_iface = container_of(ptype, struct hard_iface, batman_adv_ptype); | ||
206 | skb = skb_share_check(skb, GFP_ATOMIC); | ||
207 | |||
208 | /* skb was released by skb_share_check() */ | ||
209 | if (!skb) | ||
210 | goto err_out; | ||
211 | |||
212 | /* packet should hold at least type and version */ | ||
213 | if (unlikely(!pskb_may_pull(skb, 2))) | ||
214 | goto err_free; | ||
215 | |||
216 | /* expect a valid ethernet header here. */ | ||
217 | if (unlikely(skb->mac_len != ETH_HLEN || !skb_mac_header(skb))) | ||
218 | goto err_free; | ||
219 | |||
220 | if (!hard_iface->soft_iface) | ||
221 | goto err_free; | ||
222 | |||
223 | bat_priv = netdev_priv(hard_iface->soft_iface); | ||
224 | |||
225 | if (atomic_read(&bat_priv->mesh_state) != MESH_ACTIVE) | ||
226 | goto err_free; | ||
227 | |||
228 | /* discard frames on not active interfaces */ | ||
229 | if (hard_iface->if_status != IF_ACTIVE) | ||
230 | goto err_free; | ||
231 | |||
232 | batman_ogm_packet = (struct batman_ogm_packet *)skb->data; | ||
233 | |||
234 | if (batman_ogm_packet->header.version != COMPAT_VERSION) { | ||
235 | bat_dbg(DBG_BATMAN, bat_priv, | ||
236 | "Drop packet: incompatible batman version (%i)\n", | ||
237 | batman_ogm_packet->header.version); | ||
238 | goto err_free; | ||
239 | } | ||
240 | |||
241 | /* all receive handlers return whether they received or reused | ||
242 | * the supplied skb. if not, we have to free the skb. | ||
243 | */ | ||
244 | idx = batman_ogm_packet->header.packet_type; | ||
245 | ret = (*recv_packet_handler[idx])(skb, hard_iface); | ||
246 | |||
247 | if (ret == NET_RX_DROP) | ||
248 | kfree_skb(skb); | ||
249 | |||
250 | /* return NET_RX_SUCCESS in any case as we | ||
251 | * most probably dropped the packet for | ||
252 | * routing-logical reasons. | ||
253 | */ | ||
254 | return NET_RX_SUCCESS; | ||
255 | |||
256 | err_free: | ||
257 | kfree_skb(skb); | ||
258 | err_out: | ||
259 | return NET_RX_DROP; | ||
260 | } | ||
261 | |||
262 | static void recv_handler_init(void) | ||
263 | { | ||
264 | int i; | ||
265 | |||
266 | for (i = 0; i < ARRAY_SIZE(recv_packet_handler); i++) | ||
267 | recv_packet_handler[i] = recv_unhandled_packet; | ||
268 | |||
269 | /* batman icmp packet */ | ||
270 | recv_packet_handler[BAT_ICMP] = recv_icmp_packet; | ||
271 | /* unicast packet */ | ||
272 | recv_packet_handler[BAT_UNICAST] = recv_unicast_packet; | ||
273 | /* fragmented unicast packet */ | ||
274 | recv_packet_handler[BAT_UNICAST_FRAG] = recv_ucast_frag_packet; | ||
275 | /* broadcast packet */ | ||
276 | recv_packet_handler[BAT_BCAST] = recv_bcast_packet; | ||
277 | /* vis packet */ | ||
278 | recv_packet_handler[BAT_VIS] = recv_vis_packet; | ||
279 | /* Translation table query (request or response) */ | ||
280 | recv_packet_handler[BAT_TT_QUERY] = recv_tt_query; | ||
281 | /* Roaming advertisement */ | ||
282 | recv_packet_handler[BAT_ROAM_ADV] = recv_roam_adv; | ||
283 | } | ||
284 | |||
285 | int recv_handler_register(uint8_t packet_type, | ||
286 | int (*recv_handler)(struct sk_buff *, | ||
287 | struct hard_iface *)) | ||
288 | { | ||
289 | if (recv_packet_handler[packet_type] != &recv_unhandled_packet) | ||
290 | return -EBUSY; | ||
291 | |||
292 | recv_packet_handler[packet_type] = recv_handler; | ||
293 | return 0; | ||
294 | } | ||
295 | |||
296 | void recv_handler_unregister(uint8_t packet_type) | ||
297 | { | ||
298 | recv_packet_handler[packet_type] = recv_unhandled_packet; | ||
299 | } | ||
300 | |||
182 | static struct bat_algo_ops *bat_algo_get(char *name) | 301 | static struct bat_algo_ops *bat_algo_get(char *name) |
183 | { | 302 | { |
184 | struct bat_algo_ops *bat_algo_ops = NULL, *bat_algo_ops_tmp; | 303 | 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) | |||
210 | /* all algorithms must implement all ops (for now) */ | 329 | /* all algorithms must implement all ops (for now) */ |
211 | if (!bat_algo_ops->bat_iface_enable || | 330 | if (!bat_algo_ops->bat_iface_enable || |
212 | !bat_algo_ops->bat_iface_disable || | 331 | !bat_algo_ops->bat_iface_disable || |
332 | !bat_algo_ops->bat_iface_update_mac || | ||
213 | !bat_algo_ops->bat_primary_iface_set || | 333 | !bat_algo_ops->bat_primary_iface_set || |
214 | !bat_algo_ops->bat_ogm_update_mac || | ||
215 | !bat_algo_ops->bat_ogm_schedule || | 334 | !bat_algo_ops->bat_ogm_schedule || |
216 | !bat_algo_ops->bat_ogm_emit || | 335 | !bat_algo_ops->bat_ogm_emit) { |
217 | !bat_algo_ops->bat_ogm_receive) { | ||
218 | pr_info("Routing algo '%s' does not implement required ops\n", | 336 | pr_info("Routing algo '%s' does not implement required ops\n", |
219 | bat_algo_ops->name); | 337 | bat_algo_ops->name); |
220 | goto out; | 338 | goto out; |
diff --git a/net/batman-adv/main.h b/net/batman-adv/main.h index d9832acf558d..fd83acd48b28 100644 --- a/net/batman-adv/main.h +++ b/net/batman-adv/main.h | |||
@@ -155,6 +155,12 @@ void mesh_free(struct net_device *soft_iface); | |||
155 | void inc_module_count(void); | 155 | void inc_module_count(void); |
156 | void dec_module_count(void); | 156 | void dec_module_count(void); |
157 | int is_my_mac(const uint8_t *addr); | 157 | int is_my_mac(const uint8_t *addr); |
158 | int batman_skb_recv(struct sk_buff *skb, struct net_device *dev, | ||
159 | struct packet_type *ptype, struct net_device *orig_dev); | ||
160 | int recv_handler_register(uint8_t packet_type, | ||
161 | int (*recv_handler)(struct sk_buff *, | ||
162 | struct hard_iface *)); | ||
163 | void recv_handler_unregister(uint8_t packet_type); | ||
158 | int bat_algo_register(struct bat_algo_ops *bat_algo_ops); | 164 | int bat_algo_register(struct bat_algo_ops *bat_algo_ops); |
159 | int bat_algo_select(struct bat_priv *bat_priv, char *name); | 165 | int bat_algo_select(struct bat_priv *bat_priv, char *name); |
160 | int bat_algo_seq_print_text(struct seq_file *seq, void *offset); | 166 | int bat_algo_seq_print_text(struct seq_file *seq, void *offset); |
diff --git a/net/batman-adv/originator.c b/net/batman-adv/originator.c index ce4969885894..f4b62011ca3f 100644 --- a/net/batman-adv/originator.c +++ b/net/batman-adv/originator.c | |||
@@ -35,7 +35,8 @@ static void purge_orig(struct work_struct *work); | |||
35 | static void start_purge_timer(struct bat_priv *bat_priv) | 35 | static void start_purge_timer(struct bat_priv *bat_priv) |
36 | { | 36 | { |
37 | INIT_DELAYED_WORK(&bat_priv->orig_work, purge_orig); | 37 | INIT_DELAYED_WORK(&bat_priv->orig_work, purge_orig); |
38 | queue_delayed_work(bat_event_workqueue, &bat_priv->orig_work, 1 * HZ); | 38 | queue_delayed_work(bat_event_workqueue, |
39 | &bat_priv->orig_work, msecs_to_jiffies(1000)); | ||
39 | } | 40 | } |
40 | 41 | ||
41 | /* returns 1 if they are the same originator */ | 42 | /* returns 1 if they are the same originator */ |
@@ -84,35 +85,29 @@ struct neigh_node *orig_node_get_router(struct orig_node *orig_node) | |||
84 | return router; | 85 | return router; |
85 | } | 86 | } |
86 | 87 | ||
87 | struct neigh_node *create_neighbor(struct orig_node *orig_node, | 88 | struct neigh_node *batadv_neigh_node_new(struct hard_iface *hard_iface, |
88 | struct orig_node *orig_neigh_node, | 89 | const uint8_t *neigh_addr, |
89 | const uint8_t *neigh, | 90 | uint32_t seqno) |
90 | struct hard_iface *if_incoming) | ||
91 | { | 91 | { |
92 | struct bat_priv *bat_priv = netdev_priv(if_incoming->soft_iface); | 92 | struct bat_priv *bat_priv = netdev_priv(hard_iface->soft_iface); |
93 | struct neigh_node *neigh_node; | 93 | struct neigh_node *neigh_node; |
94 | 94 | ||
95 | bat_dbg(DBG_BATMAN, bat_priv, | ||
96 | "Creating new last-hop neighbor of originator\n"); | ||
97 | |||
98 | neigh_node = kzalloc(sizeof(*neigh_node), GFP_ATOMIC); | 95 | neigh_node = kzalloc(sizeof(*neigh_node), GFP_ATOMIC); |
99 | if (!neigh_node) | 96 | if (!neigh_node) |
100 | return NULL; | 97 | goto out; |
101 | 98 | ||
102 | INIT_HLIST_NODE(&neigh_node->list); | 99 | INIT_HLIST_NODE(&neigh_node->list); |
103 | INIT_LIST_HEAD(&neigh_node->bonding_list); | ||
104 | spin_lock_init(&neigh_node->tq_lock); | ||
105 | 100 | ||
106 | memcpy(neigh_node->addr, neigh, ETH_ALEN); | 101 | memcpy(neigh_node->addr, neigh_addr, ETH_ALEN); |
107 | neigh_node->orig_node = orig_neigh_node; | ||
108 | neigh_node->if_incoming = if_incoming; | ||
109 | 102 | ||
110 | /* extra reference for return */ | 103 | /* extra reference for return */ |
111 | atomic_set(&neigh_node->refcount, 2); | 104 | atomic_set(&neigh_node->refcount, 2); |
112 | 105 | ||
113 | spin_lock_bh(&orig_node->neigh_list_lock); | 106 | bat_dbg(DBG_BATMAN, bat_priv, |
114 | hlist_add_head_rcu(&neigh_node->list, &orig_node->neigh_list); | 107 | "Creating new neighbor %pM, initial seqno %d\n", |
115 | spin_unlock_bh(&orig_node->neigh_list_lock); | 108 | neigh_addr, seqno); |
109 | |||
110 | out: | ||
116 | return neigh_node; | 111 | return neigh_node; |
117 | } | 112 | } |
118 | 113 | ||
@@ -274,6 +269,7 @@ static bool purge_orig_neighbors(struct bat_priv *bat_priv, | |||
274 | struct hlist_node *node, *node_tmp; | 269 | struct hlist_node *node, *node_tmp; |
275 | struct neigh_node *neigh_node; | 270 | struct neigh_node *neigh_node; |
276 | bool neigh_purged = false; | 271 | bool neigh_purged = false; |
272 | unsigned long last_seen; | ||
277 | 273 | ||
278 | *best_neigh_node = NULL; | 274 | *best_neigh_node = NULL; |
279 | 275 | ||
@@ -283,11 +279,13 @@ static bool purge_orig_neighbors(struct bat_priv *bat_priv, | |||
283 | hlist_for_each_entry_safe(neigh_node, node, node_tmp, | 279 | hlist_for_each_entry_safe(neigh_node, node, node_tmp, |
284 | &orig_node->neigh_list, list) { | 280 | &orig_node->neigh_list, list) { |
285 | 281 | ||
286 | if ((has_timed_out(neigh_node->last_valid, PURGE_TIMEOUT)) || | 282 | if ((has_timed_out(neigh_node->last_seen, PURGE_TIMEOUT)) || |
287 | (neigh_node->if_incoming->if_status == IF_INACTIVE) || | 283 | (neigh_node->if_incoming->if_status == IF_INACTIVE) || |
288 | (neigh_node->if_incoming->if_status == IF_NOT_IN_USE) || | 284 | (neigh_node->if_incoming->if_status == IF_NOT_IN_USE) || |
289 | (neigh_node->if_incoming->if_status == IF_TO_BE_REMOVED)) { | 285 | (neigh_node->if_incoming->if_status == IF_TO_BE_REMOVED)) { |
290 | 286 | ||
287 | last_seen = neigh_node->last_seen; | ||
288 | |||
291 | if ((neigh_node->if_incoming->if_status == | 289 | if ((neigh_node->if_incoming->if_status == |
292 | IF_INACTIVE) || | 290 | IF_INACTIVE) || |
293 | (neigh_node->if_incoming->if_status == | 291 | (neigh_node->if_incoming->if_status == |
@@ -300,9 +298,9 @@ static bool purge_orig_neighbors(struct bat_priv *bat_priv, | |||
300 | neigh_node->if_incoming->net_dev->name); | 298 | neigh_node->if_incoming->net_dev->name); |
301 | else | 299 | else |
302 | bat_dbg(DBG_BATMAN, bat_priv, | 300 | bat_dbg(DBG_BATMAN, bat_priv, |
303 | "neighbor timeout: originator %pM, neighbor: %pM, last_valid: %lu\n", | 301 | "neighbor timeout: originator %pM, neighbor: %pM, last_seen: %u\n", |
304 | orig_node->orig, neigh_node->addr, | 302 | orig_node->orig, neigh_node->addr, |
305 | (neigh_node->last_valid / HZ)); | 303 | jiffies_to_msecs(last_seen)); |
306 | 304 | ||
307 | neigh_purged = true; | 305 | neigh_purged = true; |
308 | 306 | ||
@@ -325,10 +323,11 @@ static bool purge_orig_node(struct bat_priv *bat_priv, | |||
325 | { | 323 | { |
326 | struct neigh_node *best_neigh_node; | 324 | struct neigh_node *best_neigh_node; |
327 | 325 | ||
328 | if (has_timed_out(orig_node->last_valid, 2 * PURGE_TIMEOUT)) { | 326 | if (has_timed_out(orig_node->last_seen, 2 * PURGE_TIMEOUT)) { |
329 | bat_dbg(DBG_BATMAN, bat_priv, | 327 | bat_dbg(DBG_BATMAN, bat_priv, |
330 | "Originator timeout: originator %pM, last_valid %lu\n", | 328 | "Originator timeout: originator %pM, last_seen %u\n", |
331 | orig_node->orig, (orig_node->last_valid / HZ)); | 329 | orig_node->orig, |
330 | jiffies_to_msecs(orig_node->last_seen)); | ||
332 | return true; | 331 | return true; |
333 | } else { | 332 | } else { |
334 | if (purge_orig_neighbors(bat_priv, orig_node, | 333 | if (purge_orig_neighbors(bat_priv, orig_node, |
@@ -446,9 +445,9 @@ int orig_seq_print_text(struct seq_file *seq, void *offset) | |||
446 | goto next; | 445 | goto next; |
447 | 446 | ||
448 | last_seen_secs = jiffies_to_msecs(jiffies - | 447 | last_seen_secs = jiffies_to_msecs(jiffies - |
449 | orig_node->last_valid) / 1000; | 448 | orig_node->last_seen) / 1000; |
450 | last_seen_msecs = jiffies_to_msecs(jiffies - | 449 | last_seen_msecs = jiffies_to_msecs(jiffies - |
451 | orig_node->last_valid) % 1000; | 450 | orig_node->last_seen) % 1000; |
452 | 451 | ||
453 | seq_printf(seq, "%pM %4i.%03is (%3i) %pM [%10s]:", | 452 | seq_printf(seq, "%pM %4i.%03is (%3i) %pM [%10s]:", |
454 | orig_node->orig, last_seen_secs, | 453 | orig_node->orig, last_seen_secs, |
diff --git a/net/batman-adv/originator.h b/net/batman-adv/originator.h index 3fe2eda85652..f74d0d693359 100644 --- a/net/batman-adv/originator.h +++ b/net/batman-adv/originator.h | |||
@@ -29,10 +29,9 @@ void originator_free(struct bat_priv *bat_priv); | |||
29 | void purge_orig_ref(struct bat_priv *bat_priv); | 29 | void purge_orig_ref(struct bat_priv *bat_priv); |
30 | void orig_node_free_ref(struct orig_node *orig_node); | 30 | void orig_node_free_ref(struct orig_node *orig_node); |
31 | struct orig_node *get_orig_node(struct bat_priv *bat_priv, const uint8_t *addr); | 31 | struct orig_node *get_orig_node(struct bat_priv *bat_priv, const uint8_t *addr); |
32 | struct neigh_node *create_neighbor(struct orig_node *orig_node, | 32 | struct neigh_node *batadv_neigh_node_new(struct hard_iface *hard_iface, |
33 | struct orig_node *orig_neigh_node, | 33 | const uint8_t *neigh_addr, |
34 | const uint8_t *neigh, | 34 | uint32_t seqno); |
35 | struct hard_iface *if_incoming); | ||
36 | void neigh_node_free_ref(struct neigh_node *neigh_node); | 35 | void neigh_node_free_ref(struct neigh_node *neigh_node); |
37 | struct neigh_node *orig_node_get_router(struct orig_node *orig_node); | 36 | struct neigh_node *orig_node_get_router(struct orig_node *orig_node); |
38 | int orig_seq_print_text(struct seq_file *seq, void *offset); | 37 | int orig_seq_print_text(struct seq_file *seq, void *offset); |
diff --git a/net/batman-adv/packet.h b/net/batman-adv/packet.h index f54969c61a1e..0ee1af770798 100644 --- a/net/batman-adv/packet.h +++ b/net/batman-adv/packet.h | |||
@@ -39,6 +39,7 @@ enum bat_packettype { | |||
39 | #define COMPAT_VERSION 14 | 39 | #define COMPAT_VERSION 14 |
40 | 40 | ||
41 | enum batman_iv_flags { | 41 | enum batman_iv_flags { |
42 | NOT_BEST_NEXT_HOP = 1 << 3, | ||
42 | PRIMARIES_FIRST_HOP = 1 << 4, | 43 | PRIMARIES_FIRST_HOP = 1 << 4, |
43 | VIS_SERVER = 1 << 5, | 44 | VIS_SERVER = 1 << 5, |
44 | DIRECTLINK = 1 << 6 | 45 | DIRECTLINK = 1 << 6 |
diff --git a/net/batman-adv/routing.c b/net/batman-adv/routing.c index ff560863bc74..7ed9d8f92916 100644 --- a/net/batman-adv/routing.c +++ b/net/batman-adv/routing.c | |||
@@ -248,37 +248,35 @@ int window_protected(struct bat_priv *bat_priv, int32_t seq_num_diff, | |||
248 | return 0; | 248 | return 0; |
249 | } | 249 | } |
250 | 250 | ||
251 | int recv_bat_ogm_packet(struct sk_buff *skb, struct hard_iface *hard_iface) | 251 | bool check_management_packet(struct sk_buff *skb, |
252 | struct hard_iface *hard_iface, | ||
253 | int header_len) | ||
252 | { | 254 | { |
253 | struct bat_priv *bat_priv = netdev_priv(hard_iface->soft_iface); | ||
254 | struct ethhdr *ethhdr; | 255 | struct ethhdr *ethhdr; |
255 | 256 | ||
256 | /* drop packet if it has not necessary minimum size */ | 257 | /* drop packet if it has not necessary minimum size */ |
257 | if (unlikely(!pskb_may_pull(skb, BATMAN_OGM_HLEN))) | 258 | if (unlikely(!pskb_may_pull(skb, header_len))) |
258 | return NET_RX_DROP; | 259 | return false; |
259 | 260 | ||
260 | ethhdr = (struct ethhdr *)skb_mac_header(skb); | 261 | ethhdr = (struct ethhdr *)skb_mac_header(skb); |
261 | 262 | ||
262 | /* packet with broadcast indication but unicast recipient */ | 263 | /* packet with broadcast indication but unicast recipient */ |
263 | if (!is_broadcast_ether_addr(ethhdr->h_dest)) | 264 | if (!is_broadcast_ether_addr(ethhdr->h_dest)) |
264 | return NET_RX_DROP; | 265 | return false; |
265 | 266 | ||
266 | /* packet with broadcast sender address */ | 267 | /* packet with broadcast sender address */ |
267 | if (is_broadcast_ether_addr(ethhdr->h_source)) | 268 | if (is_broadcast_ether_addr(ethhdr->h_source)) |
268 | return NET_RX_DROP; | 269 | return false; |
269 | 270 | ||
270 | /* create a copy of the skb, if needed, to modify it. */ | 271 | /* create a copy of the skb, if needed, to modify it. */ |
271 | if (skb_cow(skb, 0) < 0) | 272 | if (skb_cow(skb, 0) < 0) |
272 | return NET_RX_DROP; | 273 | return false; |
273 | 274 | ||
274 | /* keep skb linear */ | 275 | /* keep skb linear */ |
275 | if (skb_linearize(skb) < 0) | 276 | if (skb_linearize(skb) < 0) |
276 | return NET_RX_DROP; | 277 | return false; |
277 | |||
278 | bat_priv->bat_algo_ops->bat_ogm_receive(hard_iface, skb); | ||
279 | 278 | ||
280 | kfree_skb(skb); | 279 | return true; |
281 | return NET_RX_SUCCESS; | ||
282 | } | 280 | } |
283 | 281 | ||
284 | static int recv_my_icmp_packet(struct bat_priv *bat_priv, | 282 | static int recv_my_icmp_packet(struct bat_priv *bat_priv, |
diff --git a/net/batman-adv/routing.h b/net/batman-adv/routing.h index 3d729cb17113..d6bbbebb6567 100644 --- a/net/batman-adv/routing.h +++ b/net/batman-adv/routing.h | |||
@@ -23,6 +23,9 @@ | |||
23 | #define _NET_BATMAN_ADV_ROUTING_H_ | 23 | #define _NET_BATMAN_ADV_ROUTING_H_ |
24 | 24 | ||
25 | void slide_own_bcast_window(struct hard_iface *hard_iface); | 25 | void slide_own_bcast_window(struct hard_iface *hard_iface); |
26 | bool check_management_packet(struct sk_buff *skb, | ||
27 | struct hard_iface *hard_iface, | ||
28 | int header_len); | ||
26 | void update_route(struct bat_priv *bat_priv, struct orig_node *orig_node, | 29 | void update_route(struct bat_priv *bat_priv, struct orig_node *orig_node, |
27 | struct neigh_node *neigh_node); | 30 | struct neigh_node *neigh_node); |
28 | int recv_icmp_packet(struct sk_buff *skb, struct hard_iface *recv_if); | 31 | 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); | |||
30 | int recv_ucast_frag_packet(struct sk_buff *skb, struct hard_iface *recv_if); | 33 | int recv_ucast_frag_packet(struct sk_buff *skb, struct hard_iface *recv_if); |
31 | int recv_bcast_packet(struct sk_buff *skb, struct hard_iface *recv_if); | 34 | int recv_bcast_packet(struct sk_buff *skb, struct hard_iface *recv_if); |
32 | int recv_vis_packet(struct sk_buff *skb, struct hard_iface *recv_if); | 35 | int recv_vis_packet(struct sk_buff *skb, struct hard_iface *recv_if); |
33 | int recv_bat_ogm_packet(struct sk_buff *skb, struct hard_iface *recv_if); | ||
34 | int recv_tt_query(struct sk_buff *skb, struct hard_iface *recv_if); | 36 | int recv_tt_query(struct sk_buff *skb, struct hard_iface *recv_if); |
35 | int recv_roam_adv(struct sk_buff *skb, struct hard_iface *recv_if); | 37 | int recv_roam_adv(struct sk_buff *skb, struct hard_iface *recv_if); |
36 | struct neigh_node *find_router(struct bat_priv *bat_priv, | 38 | struct neigh_node *find_router(struct bat_priv *bat_priv, |
diff --git a/net/batman-adv/send.c b/net/batman-adv/send.c index 7c66b6121fa6..8e74d9763be3 100644 --- a/net/batman-adv/send.c +++ b/net/batman-adv/send.c | |||
@@ -292,7 +292,7 @@ static void send_outstanding_bcast_packet(struct work_struct *work) | |||
292 | /* if we still have some more bcasts to send */ | 292 | /* if we still have some more bcasts to send */ |
293 | if (forw_packet->num_packets < 3) { | 293 | if (forw_packet->num_packets < 3) { |
294 | _add_bcast_packet_to_list(bat_priv, forw_packet, | 294 | _add_bcast_packet_to_list(bat_priv, forw_packet, |
295 | ((5 * HZ) / 1000)); | 295 | msecs_to_jiffies(5)); |
296 | return; | 296 | return; |
297 | } | 297 | } |
298 | 298 | ||
diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c index a38d315d3cd6..2cb46f0bb163 100644 --- a/net/batman-adv/translation-table.c +++ b/net/batman-adv/translation-table.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) 2007-2012 B.A.T.M.A.N. contributors: | 2 | * Copyright (C) 2007-2012 B.A.T.M.A.N. contributors: |
3 | * | 3 | * |
4 | * Marek Lindner, Simon Wunderlich | 4 | * Marek Lindner, Simon Wunderlich, Antonio Quartulli |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or | 6 | * This program is free software; you can redistribute it and/or |
7 | * modify it under the terms of version 2 of the GNU General Public | 7 | * modify it under the terms of version 2 of the GNU General Public |
diff --git a/net/batman-adv/translation-table.h b/net/batman-adv/translation-table.h index bfebe26edd8e..593d1b31217c 100644 --- a/net/batman-adv/translation-table.h +++ b/net/batman-adv/translation-table.h | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) 2007-2012 B.A.T.M.A.N. contributors: | 2 | * Copyright (C) 2007-2012 B.A.T.M.A.N. contributors: |
3 | * | 3 | * |
4 | * Marek Lindner, Simon Wunderlich | 4 | * Marek Lindner, Simon Wunderlich, Antonio Quartulli |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or | 6 | * This program is free software; you can redistribute it and/or |
7 | * modify it under the terms of version 2 of the GNU General Public | 7 | * modify it under the terms of version 2 of the GNU General Public |
diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h index 2f4848b776a7..66a3750aa9e7 100644 --- a/net/batman-adv/types.h +++ b/net/batman-adv/types.h | |||
@@ -52,7 +52,7 @@ struct hard_iface { | |||
52 | /** | 52 | /** |
53 | * orig_node - structure for orig_list maintaining nodes of mesh | 53 | * orig_node - structure for orig_list maintaining nodes of mesh |
54 | * @primary_addr: hosts primary interface address | 54 | * @primary_addr: hosts primary interface address |
55 | * @last_valid: when last packet from this node was received | 55 | * @last_seen: when last packet from this node was received |
56 | * @bcast_seqno_reset: time when the broadcast seqno window was reset | 56 | * @bcast_seqno_reset: time when the broadcast seqno window was reset |
57 | * @batman_seqno_reset: time when the batman seqno window was reset | 57 | * @batman_seqno_reset: time when the batman seqno window was reset |
58 | * @gw_flags: flags related to gateway class | 58 | * @gw_flags: flags related to gateway class |
@@ -70,7 +70,7 @@ struct orig_node { | |||
70 | struct neigh_node __rcu *router; /* rcu protected pointer */ | 70 | struct neigh_node __rcu *router; /* rcu protected pointer */ |
71 | unsigned long *bcast_own; | 71 | unsigned long *bcast_own; |
72 | uint8_t *bcast_own_sum; | 72 | uint8_t *bcast_own_sum; |
73 | unsigned long last_valid; | 73 | unsigned long last_seen; |
74 | unsigned long bcast_seqno_reset; | 74 | unsigned long bcast_seqno_reset; |
75 | unsigned long batman_seqno_reset; | 75 | unsigned long batman_seqno_reset; |
76 | uint8_t gw_flags; | 76 | uint8_t gw_flags; |
@@ -120,7 +120,7 @@ struct gw_node { | |||
120 | 120 | ||
121 | /** | 121 | /** |
122 | * neigh_node | 122 | * neigh_node |
123 | * @last_valid: when last packet via this neighbor was received | 123 | * @last_seen: when last packet via this neighbor was received |
124 | */ | 124 | */ |
125 | struct neigh_node { | 125 | struct neigh_node { |
126 | struct hlist_node list; | 126 | struct hlist_node list; |
@@ -131,7 +131,7 @@ struct neigh_node { | |||
131 | uint8_t tq_avg; | 131 | uint8_t tq_avg; |
132 | uint8_t last_ttl; | 132 | uint8_t last_ttl; |
133 | struct list_head bonding_list; | 133 | struct list_head bonding_list; |
134 | unsigned long last_valid; | 134 | unsigned long last_seen; |
135 | DECLARE_BITMAP(real_bits, TQ_LOCAL_WINDOW_SIZE); | 135 | DECLARE_BITMAP(real_bits, TQ_LOCAL_WINDOW_SIZE); |
136 | atomic_t refcount; | 136 | atomic_t refcount; |
137 | struct rcu_head rcu; | 137 | struct rcu_head rcu; |
@@ -381,18 +381,17 @@ struct bat_algo_ops { | |||
381 | int (*bat_iface_enable)(struct hard_iface *hard_iface); | 381 | int (*bat_iface_enable)(struct hard_iface *hard_iface); |
382 | /* de-init routing info when hard-interface is disabled */ | 382 | /* de-init routing info when hard-interface is disabled */ |
383 | void (*bat_iface_disable)(struct hard_iface *hard_iface); | 383 | void (*bat_iface_disable)(struct hard_iface *hard_iface); |
384 | /* (re-)init mac addresses of the protocol information | ||
385 | * belonging to this hard-interface | ||
386 | */ | ||
387 | void (*bat_iface_update_mac)(struct hard_iface *hard_iface); | ||
384 | /* called when primary interface is selected / changed */ | 388 | /* called when primary interface is selected / changed */ |
385 | void (*bat_primary_iface_set)(struct hard_iface *hard_iface); | 389 | void (*bat_primary_iface_set)(struct hard_iface *hard_iface); |
386 | /* init mac addresses of the OGM belonging to this hard-interface */ | ||
387 | void (*bat_ogm_update_mac)(struct hard_iface *hard_iface); | ||
388 | /* prepare a new outgoing OGM for the send queue */ | 390 | /* prepare a new outgoing OGM for the send queue */ |
389 | void (*bat_ogm_schedule)(struct hard_iface *hard_iface, | 391 | void (*bat_ogm_schedule)(struct hard_iface *hard_iface, |
390 | int tt_num_changes); | 392 | int tt_num_changes); |
391 | /* send scheduled OGM */ | 393 | /* send scheduled OGM */ |
392 | void (*bat_ogm_emit)(struct forw_packet *forw_packet); | 394 | void (*bat_ogm_emit)(struct forw_packet *forw_packet); |
393 | /* receive incoming OGM */ | ||
394 | void (*bat_ogm_receive)(struct hard_iface *if_incoming, | ||
395 | struct sk_buff *skb); | ||
396 | }; | 395 | }; |
397 | 396 | ||
398 | #endif /* _NET_BATMAN_ADV_TYPES_H_ */ | 397 | #endif /* _NET_BATMAN_ADV_TYPES_H_ */ |