Changeset 1551
- Timestamp:
- 01/17/10 21:33:37 (8 months ago)
- Location:
- trunk/batman-adv-kernelland
- Files:
-
- 12 modified
-
hard-interface.c (modified) (1 diff)
-
main.c (modified) (2 diffs)
-
main.h (modified) (2 diffs)
-
originator.c (modified) (1 diff)
-
packet.h (modified) (1 diff)
-
proc.c (modified) (5 diffs)
-
proc.h (modified) (1 diff)
-
routing.c (modified) (6 diffs)
-
routing.h (modified) (1 diff)
-
send.c (modified) (2 diffs)
-
soft-interface.c (modified) (4 diffs)
-
types.h (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/batman-adv-kernelland/hard-interface.c
r1529 r1551 313 313 batman_packet->packet_type = BAT_PACKET; 314 314 batman_packet->version = COMPAT_VERSION; 315 batman_packet->flags = 0x00;316 batman_packet->ttl = (batman_if->if_num > 0 ? 2 : TTL);317 batman_packet-> flags = 0;315 batman_packet->flags = batman_if->if_num > 0 ? 316 0x00 : PRIMARIES_FIRST_HOP; 317 batman_packet->ttl = batman_if->if_num > 0 ? 2 : TTL; 318 318 batman_packet->tq = TQ_MAX_VALUE; 319 319 batman_packet->num_hna = 0; -
trunk/batman-adv-kernelland/main.c
r1540 r1551 48 48 atomic_t vis_interval; 49 49 atomic_t aggregation_enabled; 50 atomic_t bonding_enabled; 50 51 int16_t num_hna; 51 52 int16_t num_ifs; … … 88 89 * for debugging now. */ 89 90 atomic_set(&aggregation_enabled, 1); 91 atomic_set(&bonding_enabled, 0); 90 92 atomic_set(&gw_mode, GW_MODE_OFF); 91 93 atomic_set(&gw_srv_class, 0); -
trunk/batman-adv-kernelland/main.h
r1516 r1551 58 58 #define LOG_BUF_LEN 8192 /* has to be a power of 2 */ 59 59 #define ETH_STR_LEN 20 60 61 /* how much worse secondary interfaces may be to 62 * to be considered as bonding candidates */ 63 64 #define BONDING_TQ_THRESHOLD 50 60 65 61 66 #define MAX_AGGREGATION_BYTES 512 /* should not be bigger than 512 bytes or … … 132 137 extern atomic_t vis_interval; 133 138 extern atomic_t aggregation_enabled; 139 extern atomic_t bonding_enabled; 134 140 extern int16_t num_hna; 135 141 extern int16_t num_ifs; -
trunk/batman-adv-kernelland/originator.c
r1540 r1551 222 222 return true; 223 223 } else { 224 if (purge_orig_neighbors(orig_node, &best_neigh_node)) 224 if (purge_orig_neighbors(orig_node, &best_neigh_node)) { 225 225 update_routes(orig_node, best_neigh_node, 226 226 orig_node->hna_buff, 227 227 orig_node->hna_buff_len); 228 /* update bonding candidates, we could have lost 229 * some candidates. */ 230 update_bonding_candidates(orig_node); 231 } 228 232 } 229 233 return false; -
trunk/batman-adv-kernelland/packet.h
r1540 r1551 32 32 #define DIRECTLINK 0x40 33 33 #define VIS_SERVER 0x20 34 #define PRIMARIES_FIRST_HOP 0x10 34 35 35 36 /* ICMP message types */ -
trunk/batman-adv-kernelland/proc.c
r1540 r1551 37 37 static struct proc_dir_entry *proc_transt_global_file; 38 38 static struct proc_dir_entry *proc_vis_srv_file, *proc_vis_data_file; 39 static struct proc_dir_entry *proc_aggr_file ;39 static struct proc_dir_entry *proc_aggr_file, *proc_bond_file; 40 40 static struct proc_dir_entry *proc_gw_mode_file, *proc_gw_srv_list_file; 41 41 … … 559 559 560 560 561 static int proc_bond_read(struct seq_file *seq, void *offset) 562 { 563 seq_printf(seq, "%i\n", atomic_read(&bonding_enabled)); 564 565 return 0; 566 } 567 568 static ssize_t proc_bond_write(struct file *file, const char __user *buffer, 569 size_t count, loff_t *ppos) 570 { 571 char *bond_string; 572 int not_copied = 0; 573 unsigned long bonding_enabled_tmp; 574 int retval; 575 576 bond_string = kmalloc(count, GFP_KERNEL); 577 578 if (!bond_string) 579 return -ENOMEM; 580 581 not_copied = copy_from_user(bond_string, buffer, count); 582 bond_string[count - not_copied - 1] = 0; 583 584 retval = strict_strtoul(bond_string, 10, &bonding_enabled_tmp); 585 586 if (retval || bonding_enabled_tmp > 1) { 587 printk(KERN_ERR "batman-adv: Bonding can only be enabled (1) or disabled (0), given value: %li\n", bonding_enabled_tmp); 588 } else { 589 printk(KERN_INFO "batman-adv:Changing bonding from: %s (%i) to: %s (%li)\n", 590 (atomic_read(&bonding_enabled) == 1 ? 591 "enabled" : "disabled"), 592 atomic_read(&bonding_enabled), 593 (bonding_enabled_tmp == 1 ? "enabled" : "disabled"), 594 bonding_enabled_tmp); 595 atomic_set(&bonding_enabled, 596 (unsigned)bonding_enabled_tmp); 597 } 598 599 kfree(bond_string); 600 return count; 601 } 602 603 static int proc_bond_open(struct inode *inode, struct file *file) 604 { 605 return single_open(file, proc_bond_read, NULL); 606 } 607 561 608 /* satisfying different prototypes ... */ 562 609 static ssize_t proc_dummy_write(struct file *file, const char __user *buffer, … … 593 640 }; 594 641 642 static const struct file_operations proc_bond_fops = { 643 .owner = THIS_MODULE, 644 .open = proc_bond_open, 645 .read = seq_read, 646 .write = proc_bond_write, 647 .llseek = seq_lseek, 648 .release = single_release, 649 }; 650 595 651 static const struct file_operations proc_vis_srv_fops = { 596 652 .owner = THIS_MODULE, … … 687 743 if (proc_gw_srv_list_file) 688 744 remove_proc_entry(PROC_FILE_GW_SRV_LIST, proc_batman_dir); 745 746 if (proc_bond_file) 747 remove_proc_entry(PROC_FILE_BOND, proc_batman_dir); 748 689 749 690 750 if (proc_batman_dir) … … 816 876 } 817 877 818 return 0; 819 } 878 proc_bond_file = create_proc_entry(PROC_FILE_BOND, S_IWUSR | S_IRUGO, 879 proc_batman_dir); 880 if (proc_bond_file) { 881 proc_bond_file->proc_fops = &proc_bond_fops; 882 } else { 883 printk(KERN_ERR "batman-adv: Registering the '/proc/net/%s/%s' file failed\n", PROC_ROOT_DIR, PROC_FILE_BOND); 884 cleanup_procfs(); 885 return -EFAULT; 886 } 887 888 return 0; 889 } -
trunk/batman-adv-kernelland/proc.h
r1540 r1551 35 35 #define PROC_FILE_VIS_DATA "vis_data" 36 36 #define PROC_FILE_AGGR "aggregate_ogm" 37 #define PROC_FILE_BOND "bonding" 37 38 #define PROC_FILE_GW_MODE "gateway_mode" 38 39 #define PROC_FILE_GW_SRV_LIST "gateway_srv_list" -
trunk/batman-adv-kernelland/routing.c
r1550 r1551 364 364 } 365 365 366 /* copy primary address for bonding */ 367 static void mark_bonding_address(struct orig_node *orig_node, 368 struct orig_node *orig_neigh_node, 369 struct batman_packet *batman_packet) 370 371 { 372 /* don't care if bonding is not enabled */ 373 if (!atomic_read(&bonding_enabled)) { 374 orig_node->bond.candidates = 0; 375 return; 376 } 377 378 if (batman_packet->flags & PRIMARIES_FIRST_HOP) 379 memcpy(orig_neigh_node->primary_addr, 380 orig_node->orig, ETH_ALEN); 381 else 382 return; 383 } 384 385 /* mark possible bonding candidates in the neighbor list */ 386 void update_bonding_candidates(struct orig_node *orig_node) 387 { 388 int candidates; 389 int interference_candidate; 390 int best_tq; 391 struct neigh_node *tmp_neigh_node, *tmp_neigh_node2; 392 struct neigh_node *first_candidate, *last_candidate; 393 394 /* don't care if bonding is not enabled */ 395 if (!atomic_read(&bonding_enabled)) { 396 orig_node->bond.candidates = 0; 397 return; 398 } 399 400 /* update the candidates for this originator */ 401 if (!orig_node->router) { 402 orig_node->bond.candidates = 0; 403 return; 404 } 405 406 best_tq = orig_node->router->tq_avg; 407 408 /* update bonding candidates */ 409 410 candidates = 0; 411 412 /* mark other nodes which also received "PRIMARIES FIRST HOP" packets 413 * as "bonding partner" */ 414 415 /* first, zero the list */ 416 list_for_each_entry(tmp_neigh_node, &orig_node->neigh_list, list) { 417 tmp_neigh_node->next_bond_candidate = NULL; 418 } 419 420 first_candidate = NULL; 421 last_candidate = NULL; 422 list_for_each_entry(tmp_neigh_node, &orig_node->neigh_list, list) { 423 424 /* only consider if it has the same primary address ... */ 425 if (memcmp(orig_node->orig, 426 tmp_neigh_node->orig_node->primary_addr, 427 ETH_ALEN) != 0) 428 continue; 429 430 /* ... and is good enough to be considered */ 431 if (tmp_neigh_node->tq_avg < best_tq - BONDING_TQ_THRESHOLD) 432 continue; 433 434 /* check if we have another candidate with the same 435 * mac address or interface. If we do, we won't 436 * select this candidate because of possible interference. */ 437 438 interference_candidate = 0; 439 list_for_each_entry(tmp_neigh_node2, 440 &orig_node->neigh_list, list) { 441 442 if (tmp_neigh_node2 == tmp_neigh_node) 443 continue; 444 445 if ((tmp_neigh_node->if_incoming == 446 tmp_neigh_node2->if_incoming) 447 || (memcmp(tmp_neigh_node->addr, 448 tmp_neigh_node2->addr, ETH_ALEN) == 0)) { 449 450 interference_candidate = 1; 451 break; 452 } 453 } 454 /* don't care further if it is an interference candidate */ 455 if (interference_candidate) 456 continue; 457 458 if (first_candidate == NULL) { 459 first_candidate = tmp_neigh_node; 460 tmp_neigh_node->next_bond_candidate = first_candidate; 461 } else 462 tmp_neigh_node->next_bond_candidate = last_candidate; 463 464 last_candidate = tmp_neigh_node; 465 466 candidates++; 467 } 468 469 if (candidates > 0) { 470 first_candidate->next_bond_candidate = last_candidate; 471 orig_node->bond.selected = first_candidate; 472 } 473 474 orig_node->bond.candidates = candidates; 475 } 476 366 477 void receive_bat_packet(struct ethhdr *ethhdr, 367 478 struct batman_packet *batman_packet, … … 530 641 if_incoming, hna_buff, hna_buff_len, is_duplicate); 531 642 643 mark_bonding_address(orig_node, orig_neigh_node, batman_packet); 644 update_bonding_candidates(orig_node); 645 532 646 /* is single hop (direct) neighbor */ 533 647 if (is_single_hop_neigh) { … … 799 913 } 800 914 915 /* find a suitable router for this originator, and use 916 * bonding if possible. */ 917 struct neigh_node *find_router(struct orig_node *orig_node) 918 { 919 struct orig_node *primary_orig_node; 920 struct orig_node *router_orig; 921 struct neigh_node *router; 922 static uint8_t zero_mac[ETH_ALEN] = {0, 0, 0, 0, 0, 0}; 923 924 if (!orig_node) 925 return NULL; 926 927 if (!orig_node->router) 928 return NULL; 929 930 /* don't care if bonding is not enabled */ 931 if (!atomic_read(&bonding_enabled)) 932 return orig_node->router; 933 934 router_orig = orig_node->router->orig_node; 935 936 /* if we have something in the primary_addr, we can search 937 * for a potential bonding candidate. */ 938 if (memcmp(router_orig->primary_addr, zero_mac, ETH_ALEN) == 0) 939 return orig_node->router; 940 941 /* find the orig_node which has the primary interface. might 942 * even be the same as our orig_node in many cases */ 943 944 primary_orig_node = hash_find(orig_hash, router_orig->primary_addr); 945 if (!primary_orig_node) 946 return orig_node->router; 947 948 /* with less than 2 candidates, we can't do any 949 * bonding and prefer the original router. */ 950 951 if (primary_orig_node->bond.candidates < 2) 952 return orig_node->router; 953 954 router = primary_orig_node->bond.selected; 955 956 /* sanity check - this should never happen. */ 957 if (!router) 958 return orig_node->router; 959 960 /* select the next bonding partner ... */ 961 primary_orig_node->bond.selected = router->next_bond_candidate; 962 963 return router; 964 } 965 801 966 int recv_unicast_packet(struct sk_buff *skb) 802 967 { 803 968 struct unicast_packet *unicast_packet; 804 969 struct orig_node *orig_node; 970 struct neigh_node *router; 805 971 struct ethhdr *ethhdr; 806 972 struct batman_if *batman_if; … … 808 974 uint8_t dstaddr[ETH_ALEN]; 809 975 int hdr_size = sizeof(struct unicast_packet); 810 int ret;811 976 unsigned long flags; 812 977 … … 843 1008 } 844 1009 845 ret = NET_RX_DROP;846 1010 /* get routing information */ 847 1011 spin_lock_irqsave(&orig_hash_lock, flags); … … 849 1013 hash_find(orig_hash, unicast_packet->dest)); 850 1014 851 if ((orig_node != NULL) && 852 (orig_node->batman_if != NULL) && 853 (orig_node->router != NULL)) { 854 855 /* don't lock while sending the packets ... we therefore 856 * copy the required data before sending */ 857 batman_if = orig_node->batman_if; 858 memcpy(dstaddr, orig_node->router->addr, ETH_ALEN); 859 spin_unlock_irqrestore(&orig_hash_lock, flags); 860 861 /* create a copy of the skb, if needed, to modify it. */ 862 if (!skb_clone_writable(skb, sizeof(struct unicast_packet))) { 863 skb_old = skb; 864 skb = skb_copy(skb, GFP_ATOMIC); 865 if (!skb) 866 return NET_RX_DROP; 867 unicast_packet = (struct unicast_packet *) skb->data; 868 kfree_skb(skb_old); 869 } 870 /* decrement ttl */ 871 unicast_packet->ttl--; 872 873 /* route it */ 874 send_skb_packet(skb, batman_if, dstaddr); 875 ret = NET_RX_SUCCESS; 876 877 } else 878 spin_unlock_irqrestore(&orig_hash_lock, flags); 879 880 return ret; 1015 router = find_router(orig_node); 1016 1017 if (!router) { 1018 spin_lock_irqsave(&orig_hash_lock, flags); 1019 return NET_RX_DROP; 1020 } 1021 1022 /* don't lock while sending the packets ... we therefore 1023 * copy the required data before sending */ 1024 1025 batman_if = router->if_incoming; 1026 memcpy(dstaddr, router->addr, ETH_ALEN); 1027 1028 spin_unlock_irqrestore(&orig_hash_lock, flags); 1029 1030 /* create a copy of the skb, if needed, to modify it. */ 1031 if (!skb_clone_writable(skb, sizeof(struct unicast_packet))) { 1032 skb_old = skb; 1033 skb = skb_copy(skb, GFP_ATOMIC); 1034 if (!skb) 1035 return NET_RX_DROP; 1036 unicast_packet = (struct unicast_packet *) skb->data; 1037 kfree_skb(skb_old); 1038 } 1039 1040 /* decrement ttl */ 1041 unicast_packet->ttl--; 1042 1043 /* route it */ 1044 send_skb_packet(skb, batman_if, dstaddr); 1045 1046 return NET_RX_SUCCESS; 881 1047 } 882 1048 -
trunk/batman-adv-kernelland/routing.h
r1517 r1551 39 39 int recv_bat_packet(struct sk_buff *skb, 40 40 struct batman_if *batman_if); 41 struct neigh_node *find_router(struct orig_node *orig_node); 42 void update_bonding_candidates(struct orig_node *orig_node); -
trunk/batman-adv-kernelland/send.c
r1540 r1551 277 277 278 278 if (is_vis_server()) 279 batman_packet->flags = VIS_SERVER;279 batman_packet->flags |= VIS_SERVER; 280 280 else 281 batman_packet->flags = 0;281 batman_packet->flags &= ~VIS_SERVER; 282 282 283 283 batman_packet->gw_flags = (uint8_t)atomic_read(&gw_srv_class); … … 336 336 batman_packet->seqno = htons(batman_packet->seqno); 337 337 338 /* switch of primaries first hop flag when forwarding */ 339 batman_packet->flags &= ~PRIMARIES_FIRST_HOP; 338 340 if (directlink) 339 341 batman_packet->flags |= DIRECTLINK; -
trunk/batman-adv-kernelland/soft-interface.c
r1542 r1551 23 23 #include "soft-interface.h" 24 24 #include "hard-interface.h" 25 #include "routing.h" 25 26 #include "send.h" 26 27 #include "translation-table.h" … … 172 173 } 173 174 175 176 174 177 int interface_tx(struct sk_buff *skb, struct net_device *dev) 175 178 { … … 177 180 struct bcast_packet *bcast_packet; 178 181 struct orig_node *orig_node; 182 struct neigh_node *router; 179 183 struct ethhdr *ethhdr = (struct ethhdr *)skb->data; 180 184 struct bat_priv *priv = netdev_priv(dev); … … 239 243 orig_node = transtable_search(ethhdr->h_dest); 240 244 241 if ((orig_node) && 242 (orig_node->batman_if) && 243 (orig_node->router)) { 244 if (my_skb_push(skb, sizeof(struct unicast_packet)) < 0) 245 goto unlock; 246 247 unicast_packet = (struct unicast_packet *)skb->data; 248 249 unicast_packet->version = COMPAT_VERSION; 250 /* batman packet type: unicast */ 251 unicast_packet->packet_type = BAT_UNICAST; 252 /* set unicast ttl */ 253 unicast_packet->ttl = TTL; 254 /* copy the destination for faster routing */ 255 memcpy(unicast_packet->dest, orig_node->orig, ETH_ALEN); 256 257 /* net_dev won't be available when not active */ 258 if (orig_node->batman_if->if_active != IF_ACTIVE) 259 goto unlock; 260 261 /* don't lock while sending the packets ... we therefore 262 * copy the required data before sending */ 263 264 batman_if = orig_node->batman_if; 265 memcpy(dstaddr, orig_node->router->addr, ETH_ALEN); 266 spin_unlock_irqrestore(&orig_hash_lock, flags); 267 268 send_skb_packet(skb, batman_if, dstaddr); 269 } else { 245 router = find_router(orig_node); 246 247 if (!router) 270 248 goto unlock; 271 } 249 250 /* don't lock while sending the packets ... we therefore 251 * copy the required data before sending */ 252 253 batman_if = router->if_incoming; 254 memcpy(dstaddr, router->addr, ETH_ALEN); 255 256 spin_unlock_irqrestore(&orig_hash_lock, flags); 257 258 if (batman_if->if_active != IF_ACTIVE) 259 goto dropped; 260 261 if (my_skb_push(skb, sizeof(struct unicast_packet)) < 0) 262 goto dropped; 263 264 unicast_packet = (struct unicast_packet *)skb->data; 265 266 unicast_packet->version = COMPAT_VERSION; 267 /* batman packet type: unicast */ 268 unicast_packet->packet_type = BAT_UNICAST; 269 /* set unicast ttl */ 270 unicast_packet->ttl = TTL; 271 /* copy the destination for faster routing */ 272 memcpy(unicast_packet->dest, orig_node->orig, ETH_ALEN); 273 274 send_skb_packet(skb, batman_if, dstaddr); 272 275 } 273 276 -
trunk/batman-adv-kernelland/types.h
r1540 r1551 48 48 struct orig_node { /* structure for orig_list maintaining nodes of mesh */ 49 49 uint8_t orig[ETH_ALEN]; 50 uint8_t primary_addr[ETH_ALEN]; /* hosts primary interface address */ 50 51 struct neigh_node *router; 51 52 struct batman_if *batman_if; … … 64 65 uint16_t last_bcast_seqno; /* last broadcast sequence number received by this host */ 65 66 struct list_head neigh_list; 67 struct { 68 uint8_t candidates; /* how many candidates are available */ 69 struct neigh_node *selected; /* next bonding candidate */ 70 } bond; 66 71 }; 67 72 … … 81 86 uint8_t tq_avg; 82 87 uint8_t last_ttl; 88 struct neigh_node *next_bond_candidate; 83 89 unsigned long last_valid; /* when last packet via this neighbor was received */ 84 90 TYPE_OF_WORD real_bits[NUM_WORDS];
