aboutsummaryrefslogtreecommitdiffstats
path: root/net/decnet/dn_dev.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/decnet/dn_dev.c')
-rw-r--r--net/decnet/dn_dev.c101
1 files changed, 58 insertions, 43 deletions
diff --git a/net/decnet/dn_dev.c b/net/decnet/dn_dev.c
index 4c409b46aa35..cf26ac74a188 100644
--- a/net/decnet/dn_dev.c
+++ b/net/decnet/dn_dev.c
@@ -267,7 +267,7 @@ static int dn_forwarding_proc(ctl_table *table, int write,
267 if (table->extra1 == NULL) 267 if (table->extra1 == NULL)
268 return -EINVAL; 268 return -EINVAL;
269 269
270 dn_db = dev->dn_ptr; 270 dn_db = rcu_dereference_raw(dev->dn_ptr);
271 old = dn_db->parms.forwarding; 271 old = dn_db->parms.forwarding;
272 272
273 err = proc_dointvec(table, write, buffer, lenp, ppos); 273 err = proc_dointvec(table, write, buffer, lenp, ppos);
@@ -332,14 +332,14 @@ static struct dn_ifaddr *dn_dev_alloc_ifa(void)
332 return ifa; 332 return ifa;
333} 333}
334 334
335static __inline__ void dn_dev_free_ifa(struct dn_ifaddr *ifa) 335static void dn_dev_free_ifa(struct dn_ifaddr *ifa)
336{ 336{
337 kfree(ifa); 337 kfree_rcu(ifa, rcu);
338} 338}
339 339
340static void dn_dev_del_ifa(struct dn_dev *dn_db, struct dn_ifaddr **ifap, int destroy) 340static void dn_dev_del_ifa(struct dn_dev *dn_db, struct dn_ifaddr __rcu **ifap, int destroy)
341{ 341{
342 struct dn_ifaddr *ifa1 = *ifap; 342 struct dn_ifaddr *ifa1 = rtnl_dereference(*ifap);
343 unsigned char mac_addr[6]; 343 unsigned char mac_addr[6];
344 struct net_device *dev = dn_db->dev; 344 struct net_device *dev = dn_db->dev;
345 345
@@ -373,7 +373,9 @@ static int dn_dev_insert_ifa(struct dn_dev *dn_db, struct dn_ifaddr *ifa)
373 ASSERT_RTNL(); 373 ASSERT_RTNL();
374 374
375 /* Check for duplicates */ 375 /* Check for duplicates */
376 for(ifa1 = dn_db->ifa_list; ifa1; ifa1 = ifa1->ifa_next) { 376 for (ifa1 = rtnl_dereference(dn_db->ifa_list);
377 ifa1 != NULL;
378 ifa1 = rtnl_dereference(ifa1->ifa_next)) {
377 if (ifa1->ifa_local == ifa->ifa_local) 379 if (ifa1->ifa_local == ifa->ifa_local)
378 return -EEXIST; 380 return -EEXIST;
379 } 381 }
@@ -386,7 +388,7 @@ static int dn_dev_insert_ifa(struct dn_dev *dn_db, struct dn_ifaddr *ifa)
386 } 388 }
387 389
388 ifa->ifa_next = dn_db->ifa_list; 390 ifa->ifa_next = dn_db->ifa_list;
389 dn_db->ifa_list = ifa; 391 rcu_assign_pointer(dn_db->ifa_list, ifa);
390 392
391 dn_ifaddr_notify(RTM_NEWADDR, ifa); 393 dn_ifaddr_notify(RTM_NEWADDR, ifa);
392 blocking_notifier_call_chain(&dnaddr_chain, NETDEV_UP, ifa); 394 blocking_notifier_call_chain(&dnaddr_chain, NETDEV_UP, ifa);
@@ -396,7 +398,7 @@ static int dn_dev_insert_ifa(struct dn_dev *dn_db, struct dn_ifaddr *ifa)
396 398
397static int dn_dev_set_ifa(struct net_device *dev, struct dn_ifaddr *ifa) 399static int dn_dev_set_ifa(struct net_device *dev, struct dn_ifaddr *ifa)
398{ 400{
399 struct dn_dev *dn_db = dev->dn_ptr; 401 struct dn_dev *dn_db = rtnl_dereference(dev->dn_ptr);
400 int rv; 402 int rv;
401 403
402 if (dn_db == NULL) { 404 if (dn_db == NULL) {
@@ -425,7 +427,8 @@ int dn_dev_ioctl(unsigned int cmd, void __user *arg)
425 struct sockaddr_dn *sdn = (struct sockaddr_dn *)&ifr->ifr_addr; 427 struct sockaddr_dn *sdn = (struct sockaddr_dn *)&ifr->ifr_addr;
426 struct dn_dev *dn_db; 428 struct dn_dev *dn_db;
427 struct net_device *dev; 429 struct net_device *dev;
428 struct dn_ifaddr *ifa = NULL, **ifap = NULL; 430 struct dn_ifaddr *ifa = NULL;
431 struct dn_ifaddr __rcu **ifap = NULL;
429 int ret = 0; 432 int ret = 0;
430 433
431 if (copy_from_user(ifr, arg, DN_IFREQ_SIZE)) 434 if (copy_from_user(ifr, arg, DN_IFREQ_SIZE))
@@ -454,8 +457,10 @@ int dn_dev_ioctl(unsigned int cmd, void __user *arg)
454 goto done; 457 goto done;
455 } 458 }
456 459
457 if ((dn_db = dev->dn_ptr) != NULL) { 460 if ((dn_db = rtnl_dereference(dev->dn_ptr)) != NULL) {
458 for (ifap = &dn_db->ifa_list; (ifa=*ifap) != NULL; ifap = &ifa->ifa_next) 461 for (ifap = &dn_db->ifa_list;
462 (ifa = rtnl_dereference(*ifap)) != NULL;
463 ifap = &ifa->ifa_next)
459 if (strcmp(ifr->ifr_name, ifa->ifa_label) == 0) 464 if (strcmp(ifr->ifr_name, ifa->ifa_label) == 0)
460 break; 465 break;
461 } 466 }
@@ -558,7 +563,7 @@ static struct dn_dev *dn_dev_by_index(int ifindex)
558 563
559 dev = __dev_get_by_index(&init_net, ifindex); 564 dev = __dev_get_by_index(&init_net, ifindex);
560 if (dev) 565 if (dev)
561 dn_dev = dev->dn_ptr; 566 dn_dev = rtnl_dereference(dev->dn_ptr);
562 567
563 return dn_dev; 568 return dn_dev;
564} 569}
@@ -576,7 +581,8 @@ static int dn_nl_deladdr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
576 struct nlattr *tb[IFA_MAX+1]; 581 struct nlattr *tb[IFA_MAX+1];
577 struct dn_dev *dn_db; 582 struct dn_dev *dn_db;
578 struct ifaddrmsg *ifm; 583 struct ifaddrmsg *ifm;
579 struct dn_ifaddr *ifa, **ifap; 584 struct dn_ifaddr *ifa;
585 struct dn_ifaddr __rcu **ifap;
580 int err = -EINVAL; 586 int err = -EINVAL;
581 587
582 if (!net_eq(net, &init_net)) 588 if (!net_eq(net, &init_net))
@@ -592,7 +598,9 @@ static int dn_nl_deladdr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
592 goto errout; 598 goto errout;
593 599
594 err = -EADDRNOTAVAIL; 600 err = -EADDRNOTAVAIL;
595 for (ifap = &dn_db->ifa_list; (ifa = *ifap); ifap = &ifa->ifa_next) { 601 for (ifap = &dn_db->ifa_list;
602 (ifa = rtnl_dereference(*ifap)) != NULL;
603 ifap = &ifa->ifa_next) {
596 if (tb[IFA_LOCAL] && 604 if (tb[IFA_LOCAL] &&
597 nla_memcmp(tb[IFA_LOCAL], &ifa->ifa_local, 2)) 605 nla_memcmp(tb[IFA_LOCAL], &ifa->ifa_local, 2))
598 continue; 606 continue;
@@ -632,7 +640,7 @@ static int dn_nl_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
632 if ((dev = __dev_get_by_index(&init_net, ifm->ifa_index)) == NULL) 640 if ((dev = __dev_get_by_index(&init_net, ifm->ifa_index)) == NULL)
633 return -ENODEV; 641 return -ENODEV;
634 642
635 if ((dn_db = dev->dn_ptr) == NULL) { 643 if ((dn_db = rtnl_dereference(dev->dn_ptr)) == NULL) {
636 dn_db = dn_dev_create(dev, &err); 644 dn_db = dn_dev_create(dev, &err);
637 if (!dn_db) 645 if (!dn_db)
638 return err; 646 return err;
@@ -739,7 +747,8 @@ static int dn_nl_dump_ifaddr(struct sk_buff *skb, struct netlink_callback *cb)
739 skip_naddr = cb->args[1]; 747 skip_naddr = cb->args[1];
740 748
741 idx = 0; 749 idx = 0;
742 for_each_netdev(&init_net, dev) { 750 rcu_read_lock();
751 for_each_netdev_rcu(&init_net, dev) {
743 if (idx < skip_ndevs) 752 if (idx < skip_ndevs)
744 goto cont; 753 goto cont;
745 else if (idx > skip_ndevs) { 754 else if (idx > skip_ndevs) {
@@ -748,11 +757,11 @@ static int dn_nl_dump_ifaddr(struct sk_buff *skb, struct netlink_callback *cb)
748 skip_naddr = 0; 757 skip_naddr = 0;
749 } 758 }
750 759
751 if ((dn_db = dev->dn_ptr) == NULL) 760 if ((dn_db = rcu_dereference(dev->dn_ptr)) == NULL)
752 goto cont; 761 goto cont;
753 762
754 for (ifa = dn_db->ifa_list, dn_idx = 0; ifa; 763 for (ifa = rcu_dereference(dn_db->ifa_list), dn_idx = 0; ifa;
755 ifa = ifa->ifa_next, dn_idx++) { 764 ifa = rcu_dereference(ifa->ifa_next), dn_idx++) {
756 if (dn_idx < skip_naddr) 765 if (dn_idx < skip_naddr)
757 continue; 766 continue;
758 767
@@ -765,6 +774,7 @@ cont:
765 idx++; 774 idx++;
766 } 775 }
767done: 776done:
777 rcu_read_unlock();
768 cb->args[0] = idx; 778 cb->args[0] = idx;
769 cb->args[1] = dn_idx; 779 cb->args[1] = dn_idx;
770 780
@@ -773,21 +783,22 @@ done:
773 783
774static int dn_dev_get_first(struct net_device *dev, __le16 *addr) 784static int dn_dev_get_first(struct net_device *dev, __le16 *addr)
775{ 785{
776 struct dn_dev *dn_db = (struct dn_dev *)dev->dn_ptr; 786 struct dn_dev *dn_db;
777 struct dn_ifaddr *ifa; 787 struct dn_ifaddr *ifa;
778 int rv = -ENODEV; 788 int rv = -ENODEV;
779 789
790 rcu_read_lock();
791 dn_db = rcu_dereference(dev->dn_ptr);
780 if (dn_db == NULL) 792 if (dn_db == NULL)
781 goto out; 793 goto out;
782 794
783 rtnl_lock(); 795 ifa = rcu_dereference(dn_db->ifa_list);
784 ifa = dn_db->ifa_list;
785 if (ifa != NULL) { 796 if (ifa != NULL) {
786 *addr = ifa->ifa_local; 797 *addr = ifa->ifa_local;
787 rv = 0; 798 rv = 0;
788 } 799 }
789 rtnl_unlock();
790out: 800out:
801 rcu_read_unlock();
791 return rv; 802 return rv;
792} 803}
793 804
@@ -823,7 +834,7 @@ static void dn_send_endnode_hello(struct net_device *dev, struct dn_ifaddr *ifa)
823 struct endnode_hello_message *msg; 834 struct endnode_hello_message *msg;
824 struct sk_buff *skb = NULL; 835 struct sk_buff *skb = NULL;
825 __le16 *pktlen; 836 __le16 *pktlen;
826 struct dn_dev *dn_db = (struct dn_dev *)dev->dn_ptr; 837 struct dn_dev *dn_db = rcu_dereference_raw(dev->dn_ptr);
827 838
828 if ((skb = dn_alloc_skb(NULL, sizeof(*msg), GFP_ATOMIC)) == NULL) 839 if ((skb = dn_alloc_skb(NULL, sizeof(*msg), GFP_ATOMIC)) == NULL)
829 return; 840 return;
@@ -889,7 +900,7 @@ static int dn_am_i_a_router(struct dn_neigh *dn, struct dn_dev *dn_db, struct dn
889static void dn_send_router_hello(struct net_device *dev, struct dn_ifaddr *ifa) 900static void dn_send_router_hello(struct net_device *dev, struct dn_ifaddr *ifa)
890{ 901{
891 int n; 902 int n;
892 struct dn_dev *dn_db = dev->dn_ptr; 903 struct dn_dev *dn_db = rcu_dereference_raw(dev->dn_ptr);
893 struct dn_neigh *dn = (struct dn_neigh *)dn_db->router; 904 struct dn_neigh *dn = (struct dn_neigh *)dn_db->router;
894 struct sk_buff *skb; 905 struct sk_buff *skb;
895 size_t size; 906 size_t size;
@@ -960,7 +971,7 @@ static void dn_send_router_hello(struct net_device *dev, struct dn_ifaddr *ifa)
960 971
961static void dn_send_brd_hello(struct net_device *dev, struct dn_ifaddr *ifa) 972static void dn_send_brd_hello(struct net_device *dev, struct dn_ifaddr *ifa)
962{ 973{
963 struct dn_dev *dn_db = (struct dn_dev *)dev->dn_ptr; 974 struct dn_dev *dn_db = rcu_dereference_raw(dev->dn_ptr);
964 975
965 if (dn_db->parms.forwarding == 0) 976 if (dn_db->parms.forwarding == 0)
966 dn_send_endnode_hello(dev, ifa); 977 dn_send_endnode_hello(dev, ifa);
@@ -998,7 +1009,7 @@ static void dn_send_ptp_hello(struct net_device *dev, struct dn_ifaddr *ifa)
998 1009
999static int dn_eth_up(struct net_device *dev) 1010static int dn_eth_up(struct net_device *dev)
1000{ 1011{
1001 struct dn_dev *dn_db = dev->dn_ptr; 1012 struct dn_dev *dn_db = rcu_dereference_raw(dev->dn_ptr);
1002 1013
1003 if (dn_db->parms.forwarding == 0) 1014 if (dn_db->parms.forwarding == 0)
1004 dev_mc_add(dev, dn_rt_all_end_mcast); 1015 dev_mc_add(dev, dn_rt_all_end_mcast);
@@ -1012,7 +1023,7 @@ static int dn_eth_up(struct net_device *dev)
1012 1023
1013static void dn_eth_down(struct net_device *dev) 1024static void dn_eth_down(struct net_device *dev)
1014{ 1025{
1015 struct dn_dev *dn_db = dev->dn_ptr; 1026 struct dn_dev *dn_db = rcu_dereference_raw(dev->dn_ptr);
1016 1027
1017 if (dn_db->parms.forwarding == 0) 1028 if (dn_db->parms.forwarding == 0)
1018 dev_mc_del(dev, dn_rt_all_end_mcast); 1029 dev_mc_del(dev, dn_rt_all_end_mcast);
@@ -1025,12 +1036,16 @@ static void dn_dev_set_timer(struct net_device *dev);
1025static void dn_dev_timer_func(unsigned long arg) 1036static void dn_dev_timer_func(unsigned long arg)
1026{ 1037{
1027 struct net_device *dev = (struct net_device *)arg; 1038 struct net_device *dev = (struct net_device *)arg;
1028 struct dn_dev *dn_db = dev->dn_ptr; 1039 struct dn_dev *dn_db;
1029 struct dn_ifaddr *ifa; 1040 struct dn_ifaddr *ifa;
1030 1041
1042 rcu_read_lock();
1043 dn_db = rcu_dereference(dev->dn_ptr);
1031 if (dn_db->t3 <= dn_db->parms.t2) { 1044 if (dn_db->t3 <= dn_db->parms.t2) {
1032 if (dn_db->parms.timer3) { 1045 if (dn_db->parms.timer3) {
1033 for(ifa = dn_db->ifa_list; ifa; ifa = ifa->ifa_next) { 1046 for (ifa = rcu_dereference(dn_db->ifa_list);
1047 ifa;
1048 ifa = rcu_dereference(ifa->ifa_next)) {
1034 if (!(ifa->ifa_flags & IFA_F_SECONDARY)) 1049 if (!(ifa->ifa_flags & IFA_F_SECONDARY))
1035 dn_db->parms.timer3(dev, ifa); 1050 dn_db->parms.timer3(dev, ifa);
1036 } 1051 }
@@ -1039,13 +1054,13 @@ static void dn_dev_timer_func(unsigned long arg)
1039 } else { 1054 } else {
1040 dn_db->t3 -= dn_db->parms.t2; 1055 dn_db->t3 -= dn_db->parms.t2;
1041 } 1056 }
1042 1057 rcu_read_unlock();
1043 dn_dev_set_timer(dev); 1058 dn_dev_set_timer(dev);
1044} 1059}
1045 1060
1046static void dn_dev_set_timer(struct net_device *dev) 1061static void dn_dev_set_timer(struct net_device *dev)
1047{ 1062{
1048 struct dn_dev *dn_db = dev->dn_ptr; 1063 struct dn_dev *dn_db = rcu_dereference_raw(dev->dn_ptr);
1049 1064
1050 if (dn_db->parms.t2 > dn_db->parms.t3) 1065 if (dn_db->parms.t2 > dn_db->parms.t3)
1051 dn_db->parms.t2 = dn_db->parms.t3; 1066 dn_db->parms.t2 = dn_db->parms.t3;
@@ -1077,8 +1092,8 @@ static struct dn_dev *dn_dev_create(struct net_device *dev, int *err)
1077 return NULL; 1092 return NULL;
1078 1093
1079 memcpy(&dn_db->parms, p, sizeof(struct dn_dev_parms)); 1094 memcpy(&dn_db->parms, p, sizeof(struct dn_dev_parms));
1080 smp_wmb(); 1095
1081 dev->dn_ptr = dn_db; 1096 rcu_assign_pointer(dev->dn_ptr, dn_db);
1082 dn_db->dev = dev; 1097 dn_db->dev = dev;
1083 init_timer(&dn_db->timer); 1098 init_timer(&dn_db->timer);
1084 1099
@@ -1086,7 +1101,7 @@ static struct dn_dev *dn_dev_create(struct net_device *dev, int *err)
1086 1101
1087 dn_db->neigh_parms = neigh_parms_alloc(dev, &dn_neigh_table); 1102 dn_db->neigh_parms = neigh_parms_alloc(dev, &dn_neigh_table);
1088 if (!dn_db->neigh_parms) { 1103 if (!dn_db->neigh_parms) {
1089 dev->dn_ptr = NULL; 1104 rcu_assign_pointer(dev->dn_ptr, NULL);
1090 kfree(dn_db); 1105 kfree(dn_db);
1091 return NULL; 1106 return NULL;
1092 } 1107 }
@@ -1112,7 +1127,7 @@ static struct dn_dev *dn_dev_create(struct net_device *dev, int *err)
1112/* 1127/*
1113 * This processes a device up event. We only start up 1128 * This processes a device up event. We only start up
1114 * the loopback device & ethernet devices with correct 1129 * the loopback device & ethernet devices with correct
1115 * MAC addreses automatically. Others must be started 1130 * MAC addresses automatically. Others must be started
1116 * specifically. 1131 * specifically.
1117 * 1132 *
1118 * FIXME: How should we configure the loopback address ? If we could dispense 1133 * FIXME: How should we configure the loopback address ? If we could dispense
@@ -1125,7 +1140,7 @@ void dn_dev_up(struct net_device *dev)
1125 struct dn_ifaddr *ifa; 1140 struct dn_ifaddr *ifa;
1126 __le16 addr = decnet_address; 1141 __le16 addr = decnet_address;
1127 int maybe_default = 0; 1142 int maybe_default = 0;
1128 struct dn_dev *dn_db = (struct dn_dev *)dev->dn_ptr; 1143 struct dn_dev *dn_db = rtnl_dereference(dev->dn_ptr);
1129 1144
1130 if ((dev->type != ARPHRD_ETHER) && (dev->type != ARPHRD_LOOPBACK)) 1145 if ((dev->type != ARPHRD_ETHER) && (dev->type != ARPHRD_LOOPBACK))
1131 return; 1146 return;
@@ -1176,7 +1191,7 @@ void dn_dev_up(struct net_device *dev)
1176 1191
1177static void dn_dev_delete(struct net_device *dev) 1192static void dn_dev_delete(struct net_device *dev)
1178{ 1193{
1179 struct dn_dev *dn_db = dev->dn_ptr; 1194 struct dn_dev *dn_db = rtnl_dereference(dev->dn_ptr);
1180 1195
1181 if (dn_db == NULL) 1196 if (dn_db == NULL)
1182 return; 1197 return;
@@ -1204,13 +1219,13 @@ static void dn_dev_delete(struct net_device *dev)
1204 1219
1205void dn_dev_down(struct net_device *dev) 1220void dn_dev_down(struct net_device *dev)
1206{ 1221{
1207 struct dn_dev *dn_db = dev->dn_ptr; 1222 struct dn_dev *dn_db = rtnl_dereference(dev->dn_ptr);
1208 struct dn_ifaddr *ifa; 1223 struct dn_ifaddr *ifa;
1209 1224
1210 if (dn_db == NULL) 1225 if (dn_db == NULL)
1211 return; 1226 return;
1212 1227
1213 while((ifa = dn_db->ifa_list) != NULL) { 1228 while ((ifa = rtnl_dereference(dn_db->ifa_list)) != NULL) {
1214 dn_dev_del_ifa(dn_db, &dn_db->ifa_list, 0); 1229 dn_dev_del_ifa(dn_db, &dn_db->ifa_list, 0);
1215 dn_dev_free_ifa(ifa); 1230 dn_dev_free_ifa(ifa);
1216 } 1231 }
@@ -1270,7 +1285,7 @@ static inline int is_dn_dev(struct net_device *dev)
1270} 1285}
1271 1286
1272static void *dn_dev_seq_start(struct seq_file *seq, loff_t *pos) 1287static void *dn_dev_seq_start(struct seq_file *seq, loff_t *pos)
1273 __acquires(rcu) 1288 __acquires(RCU)
1274{ 1289{
1275 int i; 1290 int i;
1276 struct net_device *dev; 1291 struct net_device *dev;
@@ -1313,7 +1328,7 @@ static void *dn_dev_seq_next(struct seq_file *seq, void *v, loff_t *pos)
1313} 1328}
1314 1329
1315static void dn_dev_seq_stop(struct seq_file *seq, void *v) 1330static void dn_dev_seq_stop(struct seq_file *seq, void *v)
1316 __releases(rcu) 1331 __releases(RCU)
1317{ 1332{
1318 rcu_read_unlock(); 1333 rcu_read_unlock();
1319} 1334}
@@ -1340,7 +1355,7 @@ static int dn_dev_seq_show(struct seq_file *seq, void *v)
1340 struct net_device *dev = v; 1355 struct net_device *dev = v;
1341 char peer_buf[DN_ASCBUF_LEN]; 1356 char peer_buf[DN_ASCBUF_LEN];
1342 char router_buf[DN_ASCBUF_LEN]; 1357 char router_buf[DN_ASCBUF_LEN];
1343 struct dn_dev *dn_db = dev->dn_ptr; 1358 struct dn_dev *dn_db = rcu_dereference(dev->dn_ptr);
1344 1359
1345 seq_printf(seq, "%-8s %1s %04u %04u %04lu %04lu" 1360 seq_printf(seq, "%-8s %1s %04u %04u %04lu %04lu"
1346 " %04hu %03d %02x %-10s %-7s %-7s\n", 1361 " %04hu %03d %02x %-10s %-7s %-7s\n",