diff options
Diffstat (limited to 'net/netrom/nr_route.c')
-rw-r--r-- | net/netrom/nr_route.c | 80 |
1 files changed, 24 insertions, 56 deletions
diff --git a/net/netrom/nr_route.c b/net/netrom/nr_route.c index 4eb1ac9a7679..44059d0c8dd1 100644 --- a/net/netrom/nr_route.c +++ b/net/netrom/nr_route.c | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <linux/string.h> | 17 | #include <linux/string.h> |
18 | #include <linux/sockios.h> | 18 | #include <linux/sockios.h> |
19 | #include <linux/net.h> | 19 | #include <linux/net.h> |
20 | #include <linux/slab.h> | ||
20 | #include <net/ax25.h> | 21 | #include <net/ax25.h> |
21 | #include <linux/inet.h> | 22 | #include <linux/inet.h> |
22 | #include <linux/netdevice.h> | 23 | #include <linux/netdevice.h> |
@@ -597,15 +598,15 @@ struct net_device *nr_dev_first(void) | |||
597 | { | 598 | { |
598 | struct net_device *dev, *first = NULL; | 599 | struct net_device *dev, *first = NULL; |
599 | 600 | ||
600 | read_lock(&dev_base_lock); | 601 | rcu_read_lock(); |
601 | for_each_netdev(&init_net, dev) { | 602 | for_each_netdev_rcu(&init_net, dev) { |
602 | if ((dev->flags & IFF_UP) && dev->type == ARPHRD_NETROM) | 603 | if ((dev->flags & IFF_UP) && dev->type == ARPHRD_NETROM) |
603 | if (first == NULL || strncmp(dev->name, first->name, 3) < 0) | 604 | if (first == NULL || strncmp(dev->name, first->name, 3) < 0) |
604 | first = dev; | 605 | first = dev; |
605 | } | 606 | } |
606 | if (first) | 607 | if (first) |
607 | dev_hold(first); | 608 | dev_hold(first); |
608 | read_unlock(&dev_base_lock); | 609 | rcu_read_unlock(); |
609 | 610 | ||
610 | return first; | 611 | return first; |
611 | } | 612 | } |
@@ -617,16 +618,17 @@ struct net_device *nr_dev_get(ax25_address *addr) | |||
617 | { | 618 | { |
618 | struct net_device *dev; | 619 | struct net_device *dev; |
619 | 620 | ||
620 | read_lock(&dev_base_lock); | 621 | rcu_read_lock(); |
621 | for_each_netdev(&init_net, dev) { | 622 | for_each_netdev_rcu(&init_net, dev) { |
622 | if ((dev->flags & IFF_UP) && dev->type == ARPHRD_NETROM && ax25cmp(addr, (ax25_address *)dev->dev_addr) == 0) { | 623 | if ((dev->flags & IFF_UP) && dev->type == ARPHRD_NETROM && |
624 | ax25cmp(addr, (ax25_address *)dev->dev_addr) == 0) { | ||
623 | dev_hold(dev); | 625 | dev_hold(dev); |
624 | goto out; | 626 | goto out; |
625 | } | 627 | } |
626 | } | 628 | } |
627 | dev = NULL; | 629 | dev = NULL; |
628 | out: | 630 | out: |
629 | read_unlock(&dev_base_lock); | 631 | rcu_read_unlock(); |
630 | return dev; | 632 | return dev; |
631 | } | 633 | } |
632 | 634 | ||
@@ -842,12 +844,13 @@ int nr_route_frame(struct sk_buff *skb, ax25_cb *ax25) | |||
842 | dptr = skb_push(skb, 1); | 844 | dptr = skb_push(skb, 1); |
843 | *dptr = AX25_P_NETROM; | 845 | *dptr = AX25_P_NETROM; |
844 | 846 | ||
845 | ax25s = ax25_send_frame(skb, 256, (ax25_address *)dev->dev_addr, &nr_neigh->callsign, nr_neigh->digipeat, nr_neigh->dev); | 847 | ax25s = nr_neigh->ax25; |
846 | if (nr_neigh->ax25 && ax25s) { | 848 | nr_neigh->ax25 = ax25_send_frame(skb, 256, |
847 | /* We were already holding this ax25_cb */ | 849 | (ax25_address *)dev->dev_addr, |
850 | &nr_neigh->callsign, | ||
851 | nr_neigh->digipeat, nr_neigh->dev); | ||
852 | if (ax25s) | ||
848 | ax25_cb_put(ax25s); | 853 | ax25_cb_put(ax25s); |
849 | } | ||
850 | nr_neigh->ax25 = ax25s; | ||
851 | 854 | ||
852 | dev_put(dev); | 855 | dev_put(dev); |
853 | ret = (nr_neigh->ax25 != NULL); | 856 | ret = (nr_neigh->ax25 != NULL); |
@@ -861,33 +864,13 @@ int nr_route_frame(struct sk_buff *skb, ax25_cb *ax25) | |||
861 | 864 | ||
862 | static void *nr_node_start(struct seq_file *seq, loff_t *pos) | 865 | static void *nr_node_start(struct seq_file *seq, loff_t *pos) |
863 | { | 866 | { |
864 | struct nr_node *nr_node; | ||
865 | struct hlist_node *node; | ||
866 | int i = 1; | ||
867 | |||
868 | spin_lock_bh(&nr_node_list_lock); | 867 | spin_lock_bh(&nr_node_list_lock); |
869 | if (*pos == 0) | 868 | return seq_hlist_start_head(&nr_node_list, *pos); |
870 | return SEQ_START_TOKEN; | ||
871 | |||
872 | nr_node_for_each(nr_node, node, &nr_node_list) { | ||
873 | if (i == *pos) | ||
874 | return nr_node; | ||
875 | ++i; | ||
876 | } | ||
877 | |||
878 | return NULL; | ||
879 | } | 869 | } |
880 | 870 | ||
881 | static void *nr_node_next(struct seq_file *seq, void *v, loff_t *pos) | 871 | static void *nr_node_next(struct seq_file *seq, void *v, loff_t *pos) |
882 | { | 872 | { |
883 | struct hlist_node *node; | 873 | return seq_hlist_next(v, &nr_node_list, pos); |
884 | ++*pos; | ||
885 | |||
886 | node = (v == SEQ_START_TOKEN) | ||
887 | ? nr_node_list.first | ||
888 | : ((struct nr_node *)v)->node_node.next; | ||
889 | |||
890 | return hlist_entry(node, struct nr_node, node_node); | ||
891 | } | 874 | } |
892 | 875 | ||
893 | static void nr_node_stop(struct seq_file *seq, void *v) | 876 | static void nr_node_stop(struct seq_file *seq, void *v) |
@@ -904,7 +887,9 @@ static int nr_node_show(struct seq_file *seq, void *v) | |||
904 | seq_puts(seq, | 887 | seq_puts(seq, |
905 | "callsign mnemonic w n qual obs neigh qual obs neigh qual obs neigh\n"); | 888 | "callsign mnemonic w n qual obs neigh qual obs neigh qual obs neigh\n"); |
906 | else { | 889 | else { |
907 | struct nr_node *nr_node = v; | 890 | struct nr_node *nr_node = hlist_entry(v, struct nr_node, |
891 | node_node); | ||
892 | |||
908 | nr_node_lock(nr_node); | 893 | nr_node_lock(nr_node); |
909 | seq_printf(seq, "%-9s %-7s %d %d", | 894 | seq_printf(seq, "%-9s %-7s %d %d", |
910 | ax2asc(buf, &nr_node->callsign), | 895 | ax2asc(buf, &nr_node->callsign), |
@@ -947,31 +932,13 @@ const struct file_operations nr_nodes_fops = { | |||
947 | 932 | ||
948 | static void *nr_neigh_start(struct seq_file *seq, loff_t *pos) | 933 | static void *nr_neigh_start(struct seq_file *seq, loff_t *pos) |
949 | { | 934 | { |
950 | struct nr_neigh *nr_neigh; | ||
951 | struct hlist_node *node; | ||
952 | int i = 1; | ||
953 | |||
954 | spin_lock_bh(&nr_neigh_list_lock); | 935 | spin_lock_bh(&nr_neigh_list_lock); |
955 | if (*pos == 0) | 936 | return seq_hlist_start_head(&nr_neigh_list, *pos); |
956 | return SEQ_START_TOKEN; | ||
957 | |||
958 | nr_neigh_for_each(nr_neigh, node, &nr_neigh_list) { | ||
959 | if (i == *pos) | ||
960 | return nr_neigh; | ||
961 | } | ||
962 | return NULL; | ||
963 | } | 937 | } |
964 | 938 | ||
965 | static void *nr_neigh_next(struct seq_file *seq, void *v, loff_t *pos) | 939 | static void *nr_neigh_next(struct seq_file *seq, void *v, loff_t *pos) |
966 | { | 940 | { |
967 | struct hlist_node *node; | 941 | return seq_hlist_next(v, &nr_neigh_list, pos); |
968 | ++*pos; | ||
969 | |||
970 | node = (v == SEQ_START_TOKEN) | ||
971 | ? nr_neigh_list.first | ||
972 | : ((struct nr_neigh *)v)->neigh_node.next; | ||
973 | |||
974 | return hlist_entry(node, struct nr_neigh, neigh_node); | ||
975 | } | 942 | } |
976 | 943 | ||
977 | static void nr_neigh_stop(struct seq_file *seq, void *v) | 944 | static void nr_neigh_stop(struct seq_file *seq, void *v) |
@@ -987,8 +954,9 @@ static int nr_neigh_show(struct seq_file *seq, void *v) | |||
987 | if (v == SEQ_START_TOKEN) | 954 | if (v == SEQ_START_TOKEN) |
988 | seq_puts(seq, "addr callsign dev qual lock count failed digipeaters\n"); | 955 | seq_puts(seq, "addr callsign dev qual lock count failed digipeaters\n"); |
989 | else { | 956 | else { |
990 | struct nr_neigh *nr_neigh = v; | 957 | struct nr_neigh *nr_neigh; |
991 | 958 | ||
959 | nr_neigh = hlist_entry(v, struct nr_neigh, neigh_node); | ||
992 | seq_printf(seq, "%05d %-9s %-4s %3d %d %3d %3d", | 960 | seq_printf(seq, "%05d %-9s %-4s %3d %d %3d %3d", |
993 | nr_neigh->number, | 961 | nr_neigh->number, |
994 | ax2asc(buf, &nr_neigh->callsign), | 962 | ax2asc(buf, &nr_neigh->callsign), |