main.c (3ea00443f1b17405ce9e1421bb7706777339926e) | main.c (09748a22f4ab7b0ab5a83c432f6e18f65f18e09b) |
---|---|
1/* Copyright (C) 2007-2016 B.A.T.M.A.N. contributors: 2 * 3 * Marek Lindner, Simon Wunderlich 4 * 5 * This program is free software; you can redistribute it and/or 6 * modify it under the terms of version 2 of the GNU General Public 7 * License as published by the Free Software Foundation. 8 * --- 17 unchanged lines hidden (view full) --- 26#include <linux/if_ether.h> 27#include <linux/if_vlan.h> 28#include <linux/init.h> 29#include <linux/ip.h> 30#include <linux/ipv6.h> 31#include <linux/kernel.h> 32#include <linux/kref.h> 33#include <linux/list.h> | 1/* Copyright (C) 2007-2016 B.A.T.M.A.N. contributors: 2 * 3 * Marek Lindner, Simon Wunderlich 4 * 5 * This program is free software; you can redistribute it and/or 6 * modify it under the terms of version 2 of the GNU General Public 7 * License as published by the Free Software Foundation. 8 * --- 17 unchanged lines hidden (view full) --- 26#include <linux/if_ether.h> 27#include <linux/if_vlan.h> 28#include <linux/init.h> 29#include <linux/ip.h> 30#include <linux/ipv6.h> 31#include <linux/kernel.h> 32#include <linux/kref.h> 33#include <linux/list.h> |
34#include <linux/lockdep.h> | |
35#include <linux/module.h> | 34#include <linux/module.h> |
36#include <linux/moduleparam.h> | |
37#include <linux/netdevice.h> | 35#include <linux/netdevice.h> |
38#include <linux/pkt_sched.h> | 36#include <linux/printk.h> |
39#include <linux/rculist.h> 40#include <linux/rcupdate.h> 41#include <linux/seq_file.h> 42#include <linux/skbuff.h> | 37#include <linux/rculist.h> 38#include <linux/rcupdate.h> 39#include <linux/seq_file.h> 40#include <linux/skbuff.h> |
43#include <linux/slab.h> | |
44#include <linux/spinlock.h> 45#include <linux/stddef.h> 46#include <linux/string.h> 47#include <linux/workqueue.h> 48#include <net/dsfield.h> 49#include <net/rtnetlink.h> 50 51#include "bat_algo.h" | 41#include <linux/spinlock.h> 42#include <linux/stddef.h> 43#include <linux/string.h> 44#include <linux/workqueue.h> 45#include <net/dsfield.h> 46#include <net/rtnetlink.h> 47 48#include "bat_algo.h" |
49#include "bat_iv_ogm.h" 50#include "bat_v.h" |
|
52#include "bridge_loop_avoidance.h" 53#include "debugfs.h" 54#include "distributed-arp-table.h" 55#include "gateway_client.h" 56#include "gateway_common.h" 57#include "hard-interface.h" 58#include "icmp_socket.h" | 51#include "bridge_loop_avoidance.h" 52#include "debugfs.h" 53#include "distributed-arp-table.h" 54#include "gateway_client.h" 55#include "gateway_common.h" 56#include "hard-interface.h" 57#include "icmp_socket.h" |
58#include "log.h" |
|
59#include "multicast.h" | 59#include "multicast.h" |
60#include "netlink.h" |
|
60#include "network-coding.h" 61#include "originator.h" 62#include "packet.h" 63#include "routing.h" 64#include "send.h" 65#include "soft-interface.h" 66#include "translation-table.h" 67 68/* List manipulations on hardif_list have to be rtnl_lock()'ed, 69 * list traversals just rcu-locked 70 */ 71struct list_head batadv_hardif_list; 72static int (*batadv_rx_handler[256])(struct sk_buff *, 73 struct batadv_hard_iface *); | 61#include "network-coding.h" 62#include "originator.h" 63#include "packet.h" 64#include "routing.h" 65#include "send.h" 66#include "soft-interface.h" 67#include "translation-table.h" 68 69/* List manipulations on hardif_list have to be rtnl_lock()'ed, 70 * list traversals just rcu-locked 71 */ 72struct list_head batadv_hardif_list; 73static int (*batadv_rx_handler[256])(struct sk_buff *, 74 struct batadv_hard_iface *); |
74char batadv_routing_algo[20] = "BATMAN_IV"; 75static struct hlist_head batadv_algo_list; | |
76 77unsigned char batadv_broadcast_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; 78 79struct workqueue_struct *batadv_event_workqueue; 80 81static void batadv_recv_handler_init(void); 82 83static int __init batadv_init(void) 84{ 85 INIT_LIST_HEAD(&batadv_hardif_list); | 75 76unsigned char batadv_broadcast_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; 77 78struct workqueue_struct *batadv_event_workqueue; 79 80static void batadv_recv_handler_init(void); 81 82static int __init batadv_init(void) 83{ 84 INIT_LIST_HEAD(&batadv_hardif_list); |
86 INIT_HLIST_HEAD(&batadv_algo_list); | 85 batadv_algo_init(); |
87 88 batadv_recv_handler_init(); 89 90 batadv_v_init(); 91 batadv_iv_init(); 92 batadv_nc_init(); 93 94 batadv_event_workqueue = create_singlethread_workqueue("bat_events"); 95 96 if (!batadv_event_workqueue) 97 return -ENOMEM; 98 99 batadv_socket_init(); 100 batadv_debugfs_init(); 101 102 register_netdevice_notifier(&batadv_hard_if_notifier); 103 rtnl_link_register(&batadv_link_ops); | 86 87 batadv_recv_handler_init(); 88 89 batadv_v_init(); 90 batadv_iv_init(); 91 batadv_nc_init(); 92 93 batadv_event_workqueue = create_singlethread_workqueue("bat_events"); 94 95 if (!batadv_event_workqueue) 96 return -ENOMEM; 97 98 batadv_socket_init(); 99 batadv_debugfs_init(); 100 101 register_netdevice_notifier(&batadv_hard_if_notifier); 102 rtnl_link_register(&batadv_link_ops); |
103 batadv_netlink_register(); |
|
104 105 pr_info("B.A.T.M.A.N. advanced %s (compatibility version %i) loaded\n", 106 BATADV_SOURCE_VERSION, BATADV_COMPAT_VERSION); 107 108 return 0; 109} 110 111static void __exit batadv_exit(void) 112{ 113 batadv_debugfs_destroy(); | 104 105 pr_info("B.A.T.M.A.N. advanced %s (compatibility version %i) loaded\n", 106 BATADV_SOURCE_VERSION, BATADV_COMPAT_VERSION); 107 108 return 0; 109} 110 111static void __exit batadv_exit(void) 112{ 113 batadv_debugfs_destroy(); |
114 batadv_netlink_unregister(); |
|
114 rtnl_link_unregister(&batadv_link_ops); 115 unregister_netdevice_notifier(&batadv_hard_if_notifier); 116 batadv_hardif_remove_interfaces(); 117 118 flush_workqueue(batadv_event_workqueue); 119 destroy_workqueue(batadv_event_workqueue); 120 batadv_event_workqueue = NULL; 121 --- 411 unchanged lines hidden (view full) --- 533 return 0; 534} 535 536void batadv_recv_handler_unregister(u8 packet_type) 537{ 538 batadv_rx_handler[packet_type] = batadv_recv_unhandled_packet; 539} 540 | 115 rtnl_link_unregister(&batadv_link_ops); 116 unregister_netdevice_notifier(&batadv_hard_if_notifier); 117 batadv_hardif_remove_interfaces(); 118 119 flush_workqueue(batadv_event_workqueue); 120 destroy_workqueue(batadv_event_workqueue); 121 batadv_event_workqueue = NULL; 122 --- 411 unchanged lines hidden (view full) --- 534 return 0; 535} 536 537void batadv_recv_handler_unregister(u8 packet_type) 538{ 539 batadv_rx_handler[packet_type] = batadv_recv_unhandled_packet; 540} 541 |
541static struct batadv_algo_ops *batadv_algo_get(char *name) 542{ 543 struct batadv_algo_ops *bat_algo_ops = NULL, *bat_algo_ops_tmp; 544 545 hlist_for_each_entry(bat_algo_ops_tmp, &batadv_algo_list, list) { 546 if (strcmp(bat_algo_ops_tmp->name, name) != 0) 547 continue; 548 549 bat_algo_ops = bat_algo_ops_tmp; 550 break; 551 } 552 553 return bat_algo_ops; 554} 555 556int batadv_algo_register(struct batadv_algo_ops *bat_algo_ops) 557{ 558 struct batadv_algo_ops *bat_algo_ops_tmp; 559 560 bat_algo_ops_tmp = batadv_algo_get(bat_algo_ops->name); 561 if (bat_algo_ops_tmp) { 562 pr_info("Trying to register already registered routing algorithm: %s\n", 563 bat_algo_ops->name); 564 return -EEXIST; 565 } 566 567 /* all algorithms must implement all ops (for now) */ 568 if (!bat_algo_ops->bat_iface_enable || 569 !bat_algo_ops->bat_iface_disable || 570 !bat_algo_ops->bat_iface_update_mac || 571 !bat_algo_ops->bat_primary_iface_set || 572 !bat_algo_ops->bat_neigh_cmp || 573 !bat_algo_ops->bat_neigh_is_similar_or_better) { 574 pr_info("Routing algo '%s' does not implement required ops\n", 575 bat_algo_ops->name); 576 return -EINVAL; 577 } 578 579 INIT_HLIST_NODE(&bat_algo_ops->list); 580 hlist_add_head(&bat_algo_ops->list, &batadv_algo_list); 581 582 return 0; 583} 584 585int batadv_algo_select(struct batadv_priv *bat_priv, char *name) 586{ 587 struct batadv_algo_ops *bat_algo_ops; 588 589 bat_algo_ops = batadv_algo_get(name); 590 if (!bat_algo_ops) 591 return -EINVAL; 592 593 bat_priv->bat_algo_ops = bat_algo_ops; 594 595 return 0; 596} 597 598int batadv_algo_seq_print_text(struct seq_file *seq, void *offset) 599{ 600 struct batadv_algo_ops *bat_algo_ops; 601 602 seq_puts(seq, "Available routing algorithms:\n"); 603 604 hlist_for_each_entry(bat_algo_ops, &batadv_algo_list, list) { 605 seq_printf(seq, " * %s\n", bat_algo_ops->name); 606 } 607 608 return 0; 609} 610 | |
611/** 612 * batadv_skb_crc32 - calculate CRC32 of the whole packet and skip bytes in 613 * the header 614 * @skb: skb pointing to fragmented socket buffers 615 * @payload_ptr: Pointer to position inside the head buffer of the skb 616 * marking the start of the data to be CRC'ed 617 * 618 * payload_ptr must always point to an address in the skb head buffer and not to --- 18 unchanged lines hidden (view full) --- 637 crc = crc32c(crc, data, len); 638 consumed += len; 639 } 640 641 return htonl(crc); 642} 643 644/** | 542/** 543 * batadv_skb_crc32 - calculate CRC32 of the whole packet and skip bytes in 544 * the header 545 * @skb: skb pointing to fragmented socket buffers 546 * @payload_ptr: Pointer to position inside the head buffer of the skb 547 * marking the start of the data to be CRC'ed 548 * 549 * payload_ptr must always point to an address in the skb head buffer and not to --- 18 unchanged lines hidden (view full) --- 568 crc = crc32c(crc, data, len); 569 consumed += len; 570 } 571 572 return htonl(crc); 573} 574 575/** |
645 * batadv_tvlv_handler_release - release tvlv handler from lists and queue for 646 * free after rcu grace period 647 * @ref: kref pointer of the tvlv 648 */ 649static void batadv_tvlv_handler_release(struct kref *ref) 650{ 651 struct batadv_tvlv_handler *tvlv_handler; 652 653 tvlv_handler = container_of(ref, struct batadv_tvlv_handler, refcount); 654 kfree_rcu(tvlv_handler, rcu); 655} 656 657/** 658 * batadv_tvlv_handler_put - decrement the tvlv container refcounter and 659 * possibly release it 660 * @tvlv_handler: the tvlv handler to free 661 */ 662static void batadv_tvlv_handler_put(struct batadv_tvlv_handler *tvlv_handler) 663{ 664 kref_put(&tvlv_handler->refcount, batadv_tvlv_handler_release); 665} 666 667/** 668 * batadv_tvlv_handler_get - retrieve tvlv handler from the tvlv handler list 669 * based on the provided type and version (both need to match) 670 * @bat_priv: the bat priv with all the soft interface information 671 * @type: tvlv handler type to look for 672 * @version: tvlv handler version to look for 673 * 674 * Return: tvlv handler if found or NULL otherwise. 675 */ 676static struct batadv_tvlv_handler * 677batadv_tvlv_handler_get(struct batadv_priv *bat_priv, u8 type, u8 version) 678{ 679 struct batadv_tvlv_handler *tvlv_handler_tmp, *tvlv_handler = NULL; 680 681 rcu_read_lock(); 682 hlist_for_each_entry_rcu(tvlv_handler_tmp, 683 &bat_priv->tvlv.handler_list, list) { 684 if (tvlv_handler_tmp->type != type) 685 continue; 686 687 if (tvlv_handler_tmp->version != version) 688 continue; 689 690 if (!kref_get_unless_zero(&tvlv_handler_tmp->refcount)) 691 continue; 692 693 tvlv_handler = tvlv_handler_tmp; 694 break; 695 } 696 rcu_read_unlock(); 697 698 return tvlv_handler; 699} 700 701/** 702 * batadv_tvlv_container_release - release tvlv from lists and free 703 * @ref: kref pointer of the tvlv 704 */ 705static void batadv_tvlv_container_release(struct kref *ref) 706{ 707 struct batadv_tvlv_container *tvlv; 708 709 tvlv = container_of(ref, struct batadv_tvlv_container, refcount); 710 kfree(tvlv); 711} 712 713/** 714 * batadv_tvlv_container_put - decrement the tvlv container refcounter and 715 * possibly release it 716 * @tvlv: the tvlv container to free 717 */ 718static void batadv_tvlv_container_put(struct batadv_tvlv_container *tvlv) 719{ 720 kref_put(&tvlv->refcount, batadv_tvlv_container_release); 721} 722 723/** 724 * batadv_tvlv_container_get - retrieve tvlv container from the tvlv container 725 * list based on the provided type and version (both need to match) 726 * @bat_priv: the bat priv with all the soft interface information 727 * @type: tvlv container type to look for 728 * @version: tvlv container version to look for 729 * 730 * Has to be called with the appropriate locks being acquired 731 * (tvlv.container_list_lock). 732 * 733 * Return: tvlv container if found or NULL otherwise. 734 */ 735static struct batadv_tvlv_container * 736batadv_tvlv_container_get(struct batadv_priv *bat_priv, u8 type, u8 version) 737{ 738 struct batadv_tvlv_container *tvlv_tmp, *tvlv = NULL; 739 740 lockdep_assert_held(&bat_priv->tvlv.container_list_lock); 741 742 hlist_for_each_entry(tvlv_tmp, &bat_priv->tvlv.container_list, list) { 743 if (tvlv_tmp->tvlv_hdr.type != type) 744 continue; 745 746 if (tvlv_tmp->tvlv_hdr.version != version) 747 continue; 748 749 kref_get(&tvlv_tmp->refcount); 750 tvlv = tvlv_tmp; 751 break; 752 } 753 754 return tvlv; 755} 756 757/** 758 * batadv_tvlv_container_list_size - calculate the size of the tvlv container 759 * list entries 760 * @bat_priv: the bat priv with all the soft interface information 761 * 762 * Has to be called with the appropriate locks being acquired 763 * (tvlv.container_list_lock). 764 * 765 * Return: size of all currently registered tvlv containers in bytes. 766 */ 767static u16 batadv_tvlv_container_list_size(struct batadv_priv *bat_priv) 768{ 769 struct batadv_tvlv_container *tvlv; 770 u16 tvlv_len = 0; 771 772 lockdep_assert_held(&bat_priv->tvlv.container_list_lock); 773 774 hlist_for_each_entry(tvlv, &bat_priv->tvlv.container_list, list) { 775 tvlv_len += sizeof(struct batadv_tvlv_hdr); 776 tvlv_len += ntohs(tvlv->tvlv_hdr.len); 777 } 778 779 return tvlv_len; 780} 781 782/** 783 * batadv_tvlv_container_remove - remove tvlv container from the tvlv container 784 * list 785 * @bat_priv: the bat priv with all the soft interface information 786 * @tvlv: the to be removed tvlv container 787 * 788 * Has to be called with the appropriate locks being acquired 789 * (tvlv.container_list_lock). 790 */ 791static void batadv_tvlv_container_remove(struct batadv_priv *bat_priv, 792 struct batadv_tvlv_container *tvlv) 793{ 794 lockdep_assert_held(&bat_priv->tvlv.container_list_lock); 795 796 if (!tvlv) 797 return; 798 799 hlist_del(&tvlv->list); 800 801 /* first call to decrement the counter, second call to free */ 802 batadv_tvlv_container_put(tvlv); 803 batadv_tvlv_container_put(tvlv); 804} 805 806/** 807 * batadv_tvlv_container_unregister - unregister tvlv container based on the 808 * provided type and version (both need to match) 809 * @bat_priv: the bat priv with all the soft interface information 810 * @type: tvlv container type to unregister 811 * @version: tvlv container type to unregister 812 */ 813void batadv_tvlv_container_unregister(struct batadv_priv *bat_priv, 814 u8 type, u8 version) 815{ 816 struct batadv_tvlv_container *tvlv; 817 818 spin_lock_bh(&bat_priv->tvlv.container_list_lock); 819 tvlv = batadv_tvlv_container_get(bat_priv, type, version); 820 batadv_tvlv_container_remove(bat_priv, tvlv); 821 spin_unlock_bh(&bat_priv->tvlv.container_list_lock); 822} 823 824/** 825 * batadv_tvlv_container_register - register tvlv type, version and content 826 * to be propagated with each (primary interface) OGM 827 * @bat_priv: the bat priv with all the soft interface information 828 * @type: tvlv container type 829 * @version: tvlv container version 830 * @tvlv_value: tvlv container content 831 * @tvlv_value_len: tvlv container content length 832 * 833 * If a container of the same type and version was already registered the new 834 * content is going to replace the old one. 835 */ 836void batadv_tvlv_container_register(struct batadv_priv *bat_priv, 837 u8 type, u8 version, 838 void *tvlv_value, u16 tvlv_value_len) 839{ 840 struct batadv_tvlv_container *tvlv_old, *tvlv_new; 841 842 if (!tvlv_value) 843 tvlv_value_len = 0; 844 845 tvlv_new = kzalloc(sizeof(*tvlv_new) + tvlv_value_len, GFP_ATOMIC); 846 if (!tvlv_new) 847 return; 848 849 tvlv_new->tvlv_hdr.version = version; 850 tvlv_new->tvlv_hdr.type = type; 851 tvlv_new->tvlv_hdr.len = htons(tvlv_value_len); 852 853 memcpy(tvlv_new + 1, tvlv_value, ntohs(tvlv_new->tvlv_hdr.len)); 854 INIT_HLIST_NODE(&tvlv_new->list); 855 kref_init(&tvlv_new->refcount); 856 857 spin_lock_bh(&bat_priv->tvlv.container_list_lock); 858 tvlv_old = batadv_tvlv_container_get(bat_priv, type, version); 859 batadv_tvlv_container_remove(bat_priv, tvlv_old); 860 hlist_add_head(&tvlv_new->list, &bat_priv->tvlv.container_list); 861 spin_unlock_bh(&bat_priv->tvlv.container_list_lock); 862} 863 864/** 865 * batadv_tvlv_realloc_packet_buff - reallocate packet buffer to accommodate 866 * requested packet size 867 * @packet_buff: packet buffer 868 * @packet_buff_len: packet buffer size 869 * @min_packet_len: requested packet minimum size 870 * @additional_packet_len: requested additional packet size on top of minimum 871 * size 872 * 873 * Return: true of the packet buffer could be changed to the requested size, 874 * false otherwise. 875 */ 876static bool batadv_tvlv_realloc_packet_buff(unsigned char **packet_buff, 877 int *packet_buff_len, 878 int min_packet_len, 879 int additional_packet_len) 880{ 881 unsigned char *new_buff; 882 883 new_buff = kmalloc(min_packet_len + additional_packet_len, GFP_ATOMIC); 884 885 /* keep old buffer if kmalloc should fail */ 886 if (!new_buff) 887 return false; 888 889 memcpy(new_buff, *packet_buff, min_packet_len); 890 kfree(*packet_buff); 891 *packet_buff = new_buff; 892 *packet_buff_len = min_packet_len + additional_packet_len; 893 894 return true; 895} 896 897/** 898 * batadv_tvlv_container_ogm_append - append tvlv container content to given 899 * OGM packet buffer 900 * @bat_priv: the bat priv with all the soft interface information 901 * @packet_buff: ogm packet buffer 902 * @packet_buff_len: ogm packet buffer size including ogm header and tvlv 903 * content 904 * @packet_min_len: ogm header size to be preserved for the OGM itself 905 * 906 * The ogm packet might be enlarged or shrunk depending on the current size 907 * and the size of the to-be-appended tvlv containers. 908 * 909 * Return: size of all appended tvlv containers in bytes. 910 */ 911u16 batadv_tvlv_container_ogm_append(struct batadv_priv *bat_priv, 912 unsigned char **packet_buff, 913 int *packet_buff_len, int packet_min_len) 914{ 915 struct batadv_tvlv_container *tvlv; 916 struct batadv_tvlv_hdr *tvlv_hdr; 917 u16 tvlv_value_len; 918 void *tvlv_value; 919 bool ret; 920 921 spin_lock_bh(&bat_priv->tvlv.container_list_lock); 922 tvlv_value_len = batadv_tvlv_container_list_size(bat_priv); 923 924 ret = batadv_tvlv_realloc_packet_buff(packet_buff, packet_buff_len, 925 packet_min_len, tvlv_value_len); 926 927 if (!ret) 928 goto end; 929 930 if (!tvlv_value_len) 931 goto end; 932 933 tvlv_value = (*packet_buff) + packet_min_len; 934 935 hlist_for_each_entry(tvlv, &bat_priv->tvlv.container_list, list) { 936 tvlv_hdr = tvlv_value; 937 tvlv_hdr->type = tvlv->tvlv_hdr.type; 938 tvlv_hdr->version = tvlv->tvlv_hdr.version; 939 tvlv_hdr->len = tvlv->tvlv_hdr.len; 940 tvlv_value = tvlv_hdr + 1; 941 memcpy(tvlv_value, tvlv + 1, ntohs(tvlv->tvlv_hdr.len)); 942 tvlv_value = (u8 *)tvlv_value + ntohs(tvlv->tvlv_hdr.len); 943 } 944 945end: 946 spin_unlock_bh(&bat_priv->tvlv.container_list_lock); 947 return tvlv_value_len; 948} 949 950/** 951 * batadv_tvlv_call_handler - parse the given tvlv buffer to call the 952 * appropriate handlers 953 * @bat_priv: the bat priv with all the soft interface information 954 * @tvlv_handler: tvlv callback function handling the tvlv content 955 * @ogm_source: flag indicating whether the tvlv is an ogm or a unicast packet 956 * @orig_node: orig node emitting the ogm packet 957 * @src: source mac address of the unicast packet 958 * @dst: destination mac address of the unicast packet 959 * @tvlv_value: tvlv content 960 * @tvlv_value_len: tvlv content length 961 * 962 * Return: success if handler was not found or the return value of the handler 963 * callback. 964 */ 965static int batadv_tvlv_call_handler(struct batadv_priv *bat_priv, 966 struct batadv_tvlv_handler *tvlv_handler, 967 bool ogm_source, 968 struct batadv_orig_node *orig_node, 969 u8 *src, u8 *dst, 970 void *tvlv_value, u16 tvlv_value_len) 971{ 972 if (!tvlv_handler) 973 return NET_RX_SUCCESS; 974 975 if (ogm_source) { 976 if (!tvlv_handler->ogm_handler) 977 return NET_RX_SUCCESS; 978 979 if (!orig_node) 980 return NET_RX_SUCCESS; 981 982 tvlv_handler->ogm_handler(bat_priv, orig_node, 983 BATADV_NO_FLAGS, 984 tvlv_value, tvlv_value_len); 985 tvlv_handler->flags |= BATADV_TVLV_HANDLER_OGM_CALLED; 986 } else { 987 if (!src) 988 return NET_RX_SUCCESS; 989 990 if (!dst) 991 return NET_RX_SUCCESS; 992 993 if (!tvlv_handler->unicast_handler) 994 return NET_RX_SUCCESS; 995 996 return tvlv_handler->unicast_handler(bat_priv, src, 997 dst, tvlv_value, 998 tvlv_value_len); 999 } 1000 1001 return NET_RX_SUCCESS; 1002} 1003 1004/** 1005 * batadv_tvlv_containers_process - parse the given tvlv buffer to call the 1006 * appropriate handlers 1007 * @bat_priv: the bat priv with all the soft interface information 1008 * @ogm_source: flag indicating whether the tvlv is an ogm or a unicast packet 1009 * @orig_node: orig node emitting the ogm packet 1010 * @src: source mac address of the unicast packet 1011 * @dst: destination mac address of the unicast packet 1012 * @tvlv_value: tvlv content 1013 * @tvlv_value_len: tvlv content length 1014 * 1015 * Return: success when processing an OGM or the return value of all called 1016 * handler callbacks. 1017 */ 1018int batadv_tvlv_containers_process(struct batadv_priv *bat_priv, 1019 bool ogm_source, 1020 struct batadv_orig_node *orig_node, 1021 u8 *src, u8 *dst, 1022 void *tvlv_value, u16 tvlv_value_len) 1023{ 1024 struct batadv_tvlv_handler *tvlv_handler; 1025 struct batadv_tvlv_hdr *tvlv_hdr; 1026 u16 tvlv_value_cont_len; 1027 u8 cifnotfound = BATADV_TVLV_HANDLER_OGM_CIFNOTFND; 1028 int ret = NET_RX_SUCCESS; 1029 1030 while (tvlv_value_len >= sizeof(*tvlv_hdr)) { 1031 tvlv_hdr = tvlv_value; 1032 tvlv_value_cont_len = ntohs(tvlv_hdr->len); 1033 tvlv_value = tvlv_hdr + 1; 1034 tvlv_value_len -= sizeof(*tvlv_hdr); 1035 1036 if (tvlv_value_cont_len > tvlv_value_len) 1037 break; 1038 1039 tvlv_handler = batadv_tvlv_handler_get(bat_priv, 1040 tvlv_hdr->type, 1041 tvlv_hdr->version); 1042 1043 ret |= batadv_tvlv_call_handler(bat_priv, tvlv_handler, 1044 ogm_source, orig_node, 1045 src, dst, tvlv_value, 1046 tvlv_value_cont_len); 1047 if (tvlv_handler) 1048 batadv_tvlv_handler_put(tvlv_handler); 1049 tvlv_value = (u8 *)tvlv_value + tvlv_value_cont_len; 1050 tvlv_value_len -= tvlv_value_cont_len; 1051 } 1052 1053 if (!ogm_source) 1054 return ret; 1055 1056 rcu_read_lock(); 1057 hlist_for_each_entry_rcu(tvlv_handler, 1058 &bat_priv->tvlv.handler_list, list) { 1059 if ((tvlv_handler->flags & BATADV_TVLV_HANDLER_OGM_CIFNOTFND) && 1060 !(tvlv_handler->flags & BATADV_TVLV_HANDLER_OGM_CALLED)) 1061 tvlv_handler->ogm_handler(bat_priv, orig_node, 1062 cifnotfound, NULL, 0); 1063 1064 tvlv_handler->flags &= ~BATADV_TVLV_HANDLER_OGM_CALLED; 1065 } 1066 rcu_read_unlock(); 1067 1068 return NET_RX_SUCCESS; 1069} 1070 1071/** 1072 * batadv_tvlv_ogm_receive - process an incoming ogm and call the appropriate 1073 * handlers 1074 * @bat_priv: the bat priv with all the soft interface information 1075 * @batadv_ogm_packet: ogm packet containing the tvlv containers 1076 * @orig_node: orig node emitting the ogm packet 1077 */ 1078void batadv_tvlv_ogm_receive(struct batadv_priv *bat_priv, 1079 struct batadv_ogm_packet *batadv_ogm_packet, 1080 struct batadv_orig_node *orig_node) 1081{ 1082 void *tvlv_value; 1083 u16 tvlv_value_len; 1084 1085 if (!batadv_ogm_packet) 1086 return; 1087 1088 tvlv_value_len = ntohs(batadv_ogm_packet->tvlv_len); 1089 if (!tvlv_value_len) 1090 return; 1091 1092 tvlv_value = batadv_ogm_packet + 1; 1093 1094 batadv_tvlv_containers_process(bat_priv, true, orig_node, NULL, NULL, 1095 tvlv_value, tvlv_value_len); 1096} 1097 1098/** 1099 * batadv_tvlv_handler_register - register tvlv handler based on the provided 1100 * type and version (both need to match) for ogm tvlv payload and/or unicast 1101 * payload 1102 * @bat_priv: the bat priv with all the soft interface information 1103 * @optr: ogm tvlv handler callback function. This function receives the orig 1104 * node, flags and the tvlv content as argument to process. 1105 * @uptr: unicast tvlv handler callback function. This function receives the 1106 * source & destination of the unicast packet as well as the tvlv content 1107 * to process. 1108 * @type: tvlv handler type to be registered 1109 * @version: tvlv handler version to be registered 1110 * @flags: flags to enable or disable TVLV API behavior 1111 */ 1112void batadv_tvlv_handler_register(struct batadv_priv *bat_priv, 1113 void (*optr)(struct batadv_priv *bat_priv, 1114 struct batadv_orig_node *orig, 1115 u8 flags, 1116 void *tvlv_value, 1117 u16 tvlv_value_len), 1118 int (*uptr)(struct batadv_priv *bat_priv, 1119 u8 *src, u8 *dst, 1120 void *tvlv_value, 1121 u16 tvlv_value_len), 1122 u8 type, u8 version, u8 flags) 1123{ 1124 struct batadv_tvlv_handler *tvlv_handler; 1125 1126 tvlv_handler = batadv_tvlv_handler_get(bat_priv, type, version); 1127 if (tvlv_handler) { 1128 batadv_tvlv_handler_put(tvlv_handler); 1129 return; 1130 } 1131 1132 tvlv_handler = kzalloc(sizeof(*tvlv_handler), GFP_ATOMIC); 1133 if (!tvlv_handler) 1134 return; 1135 1136 tvlv_handler->ogm_handler = optr; 1137 tvlv_handler->unicast_handler = uptr; 1138 tvlv_handler->type = type; 1139 tvlv_handler->version = version; 1140 tvlv_handler->flags = flags; 1141 kref_init(&tvlv_handler->refcount); 1142 INIT_HLIST_NODE(&tvlv_handler->list); 1143 1144 spin_lock_bh(&bat_priv->tvlv.handler_list_lock); 1145 hlist_add_head_rcu(&tvlv_handler->list, &bat_priv->tvlv.handler_list); 1146 spin_unlock_bh(&bat_priv->tvlv.handler_list_lock); 1147} 1148 1149/** 1150 * batadv_tvlv_handler_unregister - unregister tvlv handler based on the 1151 * provided type and version (both need to match) 1152 * @bat_priv: the bat priv with all the soft interface information 1153 * @type: tvlv handler type to be unregistered 1154 * @version: tvlv handler version to be unregistered 1155 */ 1156void batadv_tvlv_handler_unregister(struct batadv_priv *bat_priv, 1157 u8 type, u8 version) 1158{ 1159 struct batadv_tvlv_handler *tvlv_handler; 1160 1161 tvlv_handler = batadv_tvlv_handler_get(bat_priv, type, version); 1162 if (!tvlv_handler) 1163 return; 1164 1165 batadv_tvlv_handler_put(tvlv_handler); 1166 spin_lock_bh(&bat_priv->tvlv.handler_list_lock); 1167 hlist_del_rcu(&tvlv_handler->list); 1168 spin_unlock_bh(&bat_priv->tvlv.handler_list_lock); 1169 batadv_tvlv_handler_put(tvlv_handler); 1170} 1171 1172/** 1173 * batadv_tvlv_unicast_send - send a unicast packet with tvlv payload to the 1174 * specified host 1175 * @bat_priv: the bat priv with all the soft interface information 1176 * @src: source mac address of the unicast packet 1177 * @dst: destination mac address of the unicast packet 1178 * @type: tvlv type 1179 * @version: tvlv version 1180 * @tvlv_value: tvlv content 1181 * @tvlv_value_len: tvlv content length 1182 */ 1183void batadv_tvlv_unicast_send(struct batadv_priv *bat_priv, u8 *src, 1184 u8 *dst, u8 type, u8 version, 1185 void *tvlv_value, u16 tvlv_value_len) 1186{ 1187 struct batadv_unicast_tvlv_packet *unicast_tvlv_packet; 1188 struct batadv_tvlv_hdr *tvlv_hdr; 1189 struct batadv_orig_node *orig_node; 1190 struct sk_buff *skb; 1191 unsigned char *tvlv_buff; 1192 unsigned int tvlv_len; 1193 ssize_t hdr_len = sizeof(*unicast_tvlv_packet); 1194 1195 orig_node = batadv_orig_hash_find(bat_priv, dst); 1196 if (!orig_node) 1197 return; 1198 1199 tvlv_len = sizeof(*tvlv_hdr) + tvlv_value_len; 1200 1201 skb = netdev_alloc_skb_ip_align(NULL, ETH_HLEN + hdr_len + tvlv_len); 1202 if (!skb) 1203 goto out; 1204 1205 skb->priority = TC_PRIO_CONTROL; 1206 skb_reserve(skb, ETH_HLEN); 1207 tvlv_buff = skb_put(skb, sizeof(*unicast_tvlv_packet) + tvlv_len); 1208 unicast_tvlv_packet = (struct batadv_unicast_tvlv_packet *)tvlv_buff; 1209 unicast_tvlv_packet->packet_type = BATADV_UNICAST_TVLV; 1210 unicast_tvlv_packet->version = BATADV_COMPAT_VERSION; 1211 unicast_tvlv_packet->ttl = BATADV_TTL; 1212 unicast_tvlv_packet->reserved = 0; 1213 unicast_tvlv_packet->tvlv_len = htons(tvlv_len); 1214 unicast_tvlv_packet->align = 0; 1215 ether_addr_copy(unicast_tvlv_packet->src, src); 1216 ether_addr_copy(unicast_tvlv_packet->dst, dst); 1217 1218 tvlv_buff = (unsigned char *)(unicast_tvlv_packet + 1); 1219 tvlv_hdr = (struct batadv_tvlv_hdr *)tvlv_buff; 1220 tvlv_hdr->version = version; 1221 tvlv_hdr->type = type; 1222 tvlv_hdr->len = htons(tvlv_value_len); 1223 tvlv_buff += sizeof(*tvlv_hdr); 1224 memcpy(tvlv_buff, tvlv_value, tvlv_value_len); 1225 1226 if (batadv_send_skb_to_orig(skb, orig_node, NULL) == NET_XMIT_DROP) 1227 kfree_skb(skb); 1228out: 1229 batadv_orig_node_put(orig_node); 1230} 1231 1232/** | |
1233 * batadv_get_vid - extract the VLAN identifier from skb if any 1234 * @skb: the buffer containing the packet 1235 * @header_len: length of the batman header preceding the ethernet header 1236 * 1237 * Return: VID with the BATADV_VLAN_HAS_TAG flag when the packet embedded in the 1238 * skb is vlan tagged. Otherwise BATADV_NO_FLAGS. 1239 */ 1240unsigned short batadv_get_vid(struct sk_buff *skb, size_t header_len) --- 36 unchanged lines hidden (view full) --- 1277 if (vlan) { 1278 ap_isolation_enabled = atomic_read(&vlan->ap_isolation); 1279 batadv_softif_vlan_put(vlan); 1280 } 1281 1282 return ap_isolation_enabled; 1283} 1284 | 576 * batadv_get_vid - extract the VLAN identifier from skb if any 577 * @skb: the buffer containing the packet 578 * @header_len: length of the batman header preceding the ethernet header 579 * 580 * Return: VID with the BATADV_VLAN_HAS_TAG flag when the packet embedded in the 581 * skb is vlan tagged. Otherwise BATADV_NO_FLAGS. 582 */ 583unsigned short batadv_get_vid(struct sk_buff *skb, size_t header_len) --- 36 unchanged lines hidden (view full) --- 620 if (vlan) { 621 ap_isolation_enabled = atomic_read(&vlan->ap_isolation); 622 batadv_softif_vlan_put(vlan); 623 } 624 625 return ap_isolation_enabled; 626} 627 |
1285static int batadv_param_set_ra(const char *val, const struct kernel_param *kp) 1286{ 1287 struct batadv_algo_ops *bat_algo_ops; 1288 char *algo_name = (char *)val; 1289 size_t name_len = strlen(algo_name); 1290 1291 if (name_len > 0 && algo_name[name_len - 1] == '\n') 1292 algo_name[name_len - 1] = '\0'; 1293 1294 bat_algo_ops = batadv_algo_get(algo_name); 1295 if (!bat_algo_ops) { 1296 pr_err("Routing algorithm '%s' is not supported\n", algo_name); 1297 return -EINVAL; 1298 } 1299 1300 return param_set_copystring(algo_name, kp); 1301} 1302 1303static const struct kernel_param_ops batadv_param_ops_ra = { 1304 .set = batadv_param_set_ra, 1305 .get = param_get_string, 1306}; 1307 1308static struct kparam_string batadv_param_string_ra = { 1309 .maxlen = sizeof(batadv_routing_algo), 1310 .string = batadv_routing_algo, 1311}; 1312 1313module_param_cb(routing_algo, &batadv_param_ops_ra, &batadv_param_string_ra, 1314 0644); | |
1315module_init(batadv_init); 1316module_exit(batadv_exit); 1317 1318MODULE_LICENSE("GPL"); 1319 1320MODULE_AUTHOR(BATADV_DRIVER_AUTHOR); 1321MODULE_DESCRIPTION(BATADV_DRIVER_DESC); 1322MODULE_SUPPORTED_DEVICE(BATADV_DRIVER_DEVICE); 1323MODULE_VERSION(BATADV_SOURCE_VERSION); | 628module_init(batadv_init); 629module_exit(batadv_exit); 630 631MODULE_LICENSE("GPL"); 632 633MODULE_AUTHOR(BATADV_DRIVER_AUTHOR); 634MODULE_DESCRIPTION(BATADV_DRIVER_DESC); 635MODULE_SUPPORTED_DEVICE(BATADV_DRIVER_DEVICE); 636MODULE_VERSION(BATADV_SOURCE_VERSION); |