aboutsummaryrefslogtreecommitdiffstats
path: root/net/decnet
diff options
context:
space:
mode:
Diffstat (limited to 'net/decnet')
-rw-r--r--net/decnet/af_decnet.c6
-rw-r--r--net/decnet/dn_dev.c100
-rw-r--r--net/decnet/dn_fib.c6
-rw-r--r--net/decnet/dn_neigh.c2
-rw-r--r--net/decnet/dn_route.c137
-rw-r--r--net/decnet/dn_rules.c2
6 files changed, 147 insertions, 106 deletions
diff --git a/net/decnet/af_decnet.c b/net/decnet/af_decnet.c
index 6f97268ed85..2af15b15d1f 100644
--- a/net/decnet/af_decnet.c
+++ b/net/decnet/af_decnet.c
@@ -829,7 +829,7 @@ static int dn_confirm_accept(struct sock *sk, long *timeo, gfp_t allocation)
829 return -EINVAL; 829 return -EINVAL;
830 830
831 scp->state = DN_CC; 831 scp->state = DN_CC;
832 scp->segsize_loc = dst_metric(__sk_dst_get(sk), RTAX_ADVMSS); 832 scp->segsize_loc = dst_metric_advmss(__sk_dst_get(sk));
833 dn_send_conn_conf(sk, allocation); 833 dn_send_conn_conf(sk, allocation);
834 834
835 prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE); 835 prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE);
@@ -958,7 +958,7 @@ static int __dn_connect(struct sock *sk, struct sockaddr_dn *addr, int addrlen,
958 sk->sk_route_caps = sk->sk_dst_cache->dev->features; 958 sk->sk_route_caps = sk->sk_dst_cache->dev->features;
959 sock->state = SS_CONNECTING; 959 sock->state = SS_CONNECTING;
960 scp->state = DN_CI; 960 scp->state = DN_CI;
961 scp->segsize_loc = dst_metric(sk->sk_dst_cache, RTAX_ADVMSS); 961 scp->segsize_loc = dst_metric_advmss(sk->sk_dst_cache);
962 962
963 dn_nsp_send_conninit(sk, NSP_CI); 963 dn_nsp_send_conninit(sk, NSP_CI);
964 err = -EINPROGRESS; 964 err = -EINPROGRESS;
@@ -1850,7 +1850,7 @@ unsigned dn_mss_from_pmtu(struct net_device *dev, int mtu)
1850{ 1850{
1851 unsigned mss = 230 - DN_MAX_NSP_DATA_HEADER; 1851 unsigned mss = 230 - DN_MAX_NSP_DATA_HEADER;
1852 if (dev) { 1852 if (dev) {
1853 struct dn_dev *dn_db = dev->dn_ptr; 1853 struct dn_dev *dn_db = rcu_dereference_raw(dev->dn_ptr);
1854 mtu -= LL_RESERVED_SPACE(dev); 1854 mtu -= LL_RESERVED_SPACE(dev);
1855 if (dn_db->use_long) 1855 if (dn_db->use_long)
1856 mtu -= 21; 1856 mtu -= 21;
diff --git a/net/decnet/dn_dev.c b/net/decnet/dn_dev.c
index 9b73e0b03e3..0dcaa903e00 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,19 @@ 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_rcu(struct rcu_head *head)
336{ 336{
337 kfree(ifa); 337 kfree(container_of(head, struct dn_ifaddr, 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_free_ifa(struct dn_ifaddr *ifa)
341{ 341{
342 struct dn_ifaddr *ifa1 = *ifap; 342 call_rcu(&ifa->rcu, dn_dev_free_ifa_rcu);
343}
344
345static void dn_dev_del_ifa(struct dn_dev *dn_db, struct dn_ifaddr __rcu **ifap, int destroy)
346{
347 struct dn_ifaddr *ifa1 = rtnl_dereference(*ifap);
343 unsigned char mac_addr[6]; 348 unsigned char mac_addr[6];
344 struct net_device *dev = dn_db->dev; 349 struct net_device *dev = dn_db->dev;
345 350
@@ -373,7 +378,9 @@ static int dn_dev_insert_ifa(struct dn_dev *dn_db, struct dn_ifaddr *ifa)
373 ASSERT_RTNL(); 378 ASSERT_RTNL();
374 379
375 /* Check for duplicates */ 380 /* Check for duplicates */
376 for(ifa1 = dn_db->ifa_list; ifa1; ifa1 = ifa1->ifa_next) { 381 for (ifa1 = rtnl_dereference(dn_db->ifa_list);
382 ifa1 != NULL;
383 ifa1 = rtnl_dereference(ifa1->ifa_next)) {
377 if (ifa1->ifa_local == ifa->ifa_local) 384 if (ifa1->ifa_local == ifa->ifa_local)
378 return -EEXIST; 385 return -EEXIST;
379 } 386 }
@@ -386,7 +393,7 @@ static int dn_dev_insert_ifa(struct dn_dev *dn_db, struct dn_ifaddr *ifa)
386 } 393 }
387 394
388 ifa->ifa_next = dn_db->ifa_list; 395 ifa->ifa_next = dn_db->ifa_list;
389 dn_db->ifa_list = ifa; 396 rcu_assign_pointer(dn_db->ifa_list, ifa);
390 397
391 dn_ifaddr_notify(RTM_NEWADDR, ifa); 398 dn_ifaddr_notify(RTM_NEWADDR, ifa);
392 blocking_notifier_call_chain(&dnaddr_chain, NETDEV_UP, ifa); 399 blocking_notifier_call_chain(&dnaddr_chain, NETDEV_UP, ifa);
@@ -396,7 +403,7 @@ static int dn_dev_insert_ifa(struct dn_dev *dn_db, struct dn_ifaddr *ifa)
396 403
397static int dn_dev_set_ifa(struct net_device *dev, struct dn_ifaddr *ifa) 404static int dn_dev_set_ifa(struct net_device *dev, struct dn_ifaddr *ifa)
398{ 405{
399 struct dn_dev *dn_db = dev->dn_ptr; 406 struct dn_dev *dn_db = rtnl_dereference(dev->dn_ptr);
400 int rv; 407 int rv;
401 408
402 if (dn_db == NULL) { 409 if (dn_db == NULL) {
@@ -425,7 +432,8 @@ int dn_dev_ioctl(unsigned int cmd, void __user *arg)
425 struct sockaddr_dn *sdn = (struct sockaddr_dn *)&ifr->ifr_addr; 432 struct sockaddr_dn *sdn = (struct sockaddr_dn *)&ifr->ifr_addr;
426 struct dn_dev *dn_db; 433 struct dn_dev *dn_db;
427 struct net_device *dev; 434 struct net_device *dev;
428 struct dn_ifaddr *ifa = NULL, **ifap = NULL; 435 struct dn_ifaddr *ifa = NULL;
436 struct dn_ifaddr __rcu **ifap = NULL;
429 int ret = 0; 437 int ret = 0;
430 438
431 if (copy_from_user(ifr, arg, DN_IFREQ_SIZE)) 439 if (copy_from_user(ifr, arg, DN_IFREQ_SIZE))
@@ -454,8 +462,10 @@ int dn_dev_ioctl(unsigned int cmd, void __user *arg)
454 goto done; 462 goto done;
455 } 463 }
456 464
457 if ((dn_db = dev->dn_ptr) != NULL) { 465 if ((dn_db = rtnl_dereference(dev->dn_ptr)) != NULL) {
458 for (ifap = &dn_db->ifa_list; (ifa=*ifap) != NULL; ifap = &ifa->ifa_next) 466 for (ifap = &dn_db->ifa_list;
467 (ifa = rtnl_dereference(*ifap)) != NULL;
468 ifap = &ifa->ifa_next)
459 if (strcmp(ifr->ifr_name, ifa->ifa_label) == 0) 469 if (strcmp(ifr->ifr_name, ifa->ifa_label) == 0)
460 break; 470 break;
461 } 471 }
@@ -558,7 +568,7 @@ static struct dn_dev *dn_dev_by_index(int ifindex)
558 568
559 dev = __dev_get_by_index(&init_net, ifindex); 569 dev = __dev_get_by_index(&init_net, ifindex);
560 if (dev) 570 if (dev)
561 dn_dev = dev->dn_ptr; 571 dn_dev = rtnl_dereference(dev->dn_ptr);
562 572
563 return dn_dev; 573 return dn_dev;
564} 574}
@@ -576,7 +586,8 @@ static int dn_nl_deladdr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
576 struct nlattr *tb[IFA_MAX+1]; 586 struct nlattr *tb[IFA_MAX+1];
577 struct dn_dev *dn_db; 587 struct dn_dev *dn_db;
578 struct ifaddrmsg *ifm; 588 struct ifaddrmsg *ifm;
579 struct dn_ifaddr *ifa, **ifap; 589 struct dn_ifaddr *ifa;
590 struct dn_ifaddr __rcu **ifap;
580 int err = -EINVAL; 591 int err = -EINVAL;
581 592
582 if (!net_eq(net, &init_net)) 593 if (!net_eq(net, &init_net))
@@ -592,7 +603,9 @@ static int dn_nl_deladdr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
592 goto errout; 603 goto errout;
593 604
594 err = -EADDRNOTAVAIL; 605 err = -EADDRNOTAVAIL;
595 for (ifap = &dn_db->ifa_list; (ifa = *ifap); ifap = &ifa->ifa_next) { 606 for (ifap = &dn_db->ifa_list;
607 (ifa = rtnl_dereference(*ifap)) != NULL;
608 ifap = &ifa->ifa_next) {
596 if (tb[IFA_LOCAL] && 609 if (tb[IFA_LOCAL] &&
597 nla_memcmp(tb[IFA_LOCAL], &ifa->ifa_local, 2)) 610 nla_memcmp(tb[IFA_LOCAL], &ifa->ifa_local, 2))
598 continue; 611 continue;
@@ -632,7 +645,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) 645 if ((dev = __dev_get_by_index(&init_net, ifm->ifa_index)) == NULL)
633 return -ENODEV; 646 return -ENODEV;
634 647
635 if ((dn_db = dev->dn_ptr) == NULL) { 648 if ((dn_db = rtnl_dereference(dev->dn_ptr)) == NULL) {
636 dn_db = dn_dev_create(dev, &err); 649 dn_db = dn_dev_create(dev, &err);
637 if (!dn_db) 650 if (!dn_db)
638 return err; 651 return err;
@@ -748,11 +761,11 @@ static int dn_nl_dump_ifaddr(struct sk_buff *skb, struct netlink_callback *cb)
748 skip_naddr = 0; 761 skip_naddr = 0;
749 } 762 }
750 763
751 if ((dn_db = dev->dn_ptr) == NULL) 764 if ((dn_db = rtnl_dereference(dev->dn_ptr)) == NULL)
752 goto cont; 765 goto cont;
753 766
754 for (ifa = dn_db->ifa_list, dn_idx = 0; ifa; 767 for (ifa = rtnl_dereference(dn_db->ifa_list), dn_idx = 0; ifa;
755 ifa = ifa->ifa_next, dn_idx++) { 768 ifa = rtnl_dereference(ifa->ifa_next), dn_idx++) {
756 if (dn_idx < skip_naddr) 769 if (dn_idx < skip_naddr)
757 continue; 770 continue;
758 771
@@ -773,21 +786,22 @@ done:
773 786
774static int dn_dev_get_first(struct net_device *dev, __le16 *addr) 787static int dn_dev_get_first(struct net_device *dev, __le16 *addr)
775{ 788{
776 struct dn_dev *dn_db = (struct dn_dev *)dev->dn_ptr; 789 struct dn_dev *dn_db;
777 struct dn_ifaddr *ifa; 790 struct dn_ifaddr *ifa;
778 int rv = -ENODEV; 791 int rv = -ENODEV;
779 792
793 rcu_read_lock();
794 dn_db = rcu_dereference(dev->dn_ptr);
780 if (dn_db == NULL) 795 if (dn_db == NULL)
781 goto out; 796 goto out;
782 797
783 rtnl_lock(); 798 ifa = rcu_dereference(dn_db->ifa_list);
784 ifa = dn_db->ifa_list;
785 if (ifa != NULL) { 799 if (ifa != NULL) {
786 *addr = ifa->ifa_local; 800 *addr = ifa->ifa_local;
787 rv = 0; 801 rv = 0;
788 } 802 }
789 rtnl_unlock();
790out: 803out:
804 rcu_read_unlock();
791 return rv; 805 return rv;
792} 806}
793 807
@@ -823,7 +837,7 @@ static void dn_send_endnode_hello(struct net_device *dev, struct dn_ifaddr *ifa)
823 struct endnode_hello_message *msg; 837 struct endnode_hello_message *msg;
824 struct sk_buff *skb = NULL; 838 struct sk_buff *skb = NULL;
825 __le16 *pktlen; 839 __le16 *pktlen;
826 struct dn_dev *dn_db = (struct dn_dev *)dev->dn_ptr; 840 struct dn_dev *dn_db = rcu_dereference_raw(dev->dn_ptr);
827 841
828 if ((skb = dn_alloc_skb(NULL, sizeof(*msg), GFP_ATOMIC)) == NULL) 842 if ((skb = dn_alloc_skb(NULL, sizeof(*msg), GFP_ATOMIC)) == NULL)
829 return; 843 return;
@@ -889,7 +903,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) 903static void dn_send_router_hello(struct net_device *dev, struct dn_ifaddr *ifa)
890{ 904{
891 int n; 905 int n;
892 struct dn_dev *dn_db = dev->dn_ptr; 906 struct dn_dev *dn_db = rcu_dereference_raw(dev->dn_ptr);
893 struct dn_neigh *dn = (struct dn_neigh *)dn_db->router; 907 struct dn_neigh *dn = (struct dn_neigh *)dn_db->router;
894 struct sk_buff *skb; 908 struct sk_buff *skb;
895 size_t size; 909 size_t size;
@@ -960,7 +974,7 @@ static void dn_send_router_hello(struct net_device *dev, struct dn_ifaddr *ifa)
960 974
961static void dn_send_brd_hello(struct net_device *dev, struct dn_ifaddr *ifa) 975static void dn_send_brd_hello(struct net_device *dev, struct dn_ifaddr *ifa)
962{ 976{
963 struct dn_dev *dn_db = (struct dn_dev *)dev->dn_ptr; 977 struct dn_dev *dn_db = rcu_dereference_raw(dev->dn_ptr);
964 978
965 if (dn_db->parms.forwarding == 0) 979 if (dn_db->parms.forwarding == 0)
966 dn_send_endnode_hello(dev, ifa); 980 dn_send_endnode_hello(dev, ifa);
@@ -998,7 +1012,7 @@ static void dn_send_ptp_hello(struct net_device *dev, struct dn_ifaddr *ifa)
998 1012
999static int dn_eth_up(struct net_device *dev) 1013static int dn_eth_up(struct net_device *dev)
1000{ 1014{
1001 struct dn_dev *dn_db = dev->dn_ptr; 1015 struct dn_dev *dn_db = rcu_dereference_raw(dev->dn_ptr);
1002 1016
1003 if (dn_db->parms.forwarding == 0) 1017 if (dn_db->parms.forwarding == 0)
1004 dev_mc_add(dev, dn_rt_all_end_mcast); 1018 dev_mc_add(dev, dn_rt_all_end_mcast);
@@ -1012,7 +1026,7 @@ static int dn_eth_up(struct net_device *dev)
1012 1026
1013static void dn_eth_down(struct net_device *dev) 1027static void dn_eth_down(struct net_device *dev)
1014{ 1028{
1015 struct dn_dev *dn_db = dev->dn_ptr; 1029 struct dn_dev *dn_db = rcu_dereference_raw(dev->dn_ptr);
1016 1030
1017 if (dn_db->parms.forwarding == 0) 1031 if (dn_db->parms.forwarding == 0)
1018 dev_mc_del(dev, dn_rt_all_end_mcast); 1032 dev_mc_del(dev, dn_rt_all_end_mcast);
@@ -1025,12 +1039,16 @@ static void dn_dev_set_timer(struct net_device *dev);
1025static void dn_dev_timer_func(unsigned long arg) 1039static void dn_dev_timer_func(unsigned long arg)
1026{ 1040{
1027 struct net_device *dev = (struct net_device *)arg; 1041 struct net_device *dev = (struct net_device *)arg;
1028 struct dn_dev *dn_db = dev->dn_ptr; 1042 struct dn_dev *dn_db;
1029 struct dn_ifaddr *ifa; 1043 struct dn_ifaddr *ifa;
1030 1044
1045 rcu_read_lock();
1046 dn_db = rcu_dereference(dev->dn_ptr);
1031 if (dn_db->t3 <= dn_db->parms.t2) { 1047 if (dn_db->t3 <= dn_db->parms.t2) {
1032 if (dn_db->parms.timer3) { 1048 if (dn_db->parms.timer3) {
1033 for(ifa = dn_db->ifa_list; ifa; ifa = ifa->ifa_next) { 1049 for (ifa = rcu_dereference(dn_db->ifa_list);
1050 ifa;
1051 ifa = rcu_dereference(ifa->ifa_next)) {
1034 if (!(ifa->ifa_flags & IFA_F_SECONDARY)) 1052 if (!(ifa->ifa_flags & IFA_F_SECONDARY))
1035 dn_db->parms.timer3(dev, ifa); 1053 dn_db->parms.timer3(dev, ifa);
1036 } 1054 }
@@ -1039,13 +1057,13 @@ static void dn_dev_timer_func(unsigned long arg)
1039 } else { 1057 } else {
1040 dn_db->t3 -= dn_db->parms.t2; 1058 dn_db->t3 -= dn_db->parms.t2;
1041 } 1059 }
1042 1060 rcu_read_unlock();
1043 dn_dev_set_timer(dev); 1061 dn_dev_set_timer(dev);
1044} 1062}
1045 1063
1046static void dn_dev_set_timer(struct net_device *dev) 1064static void dn_dev_set_timer(struct net_device *dev)
1047{ 1065{
1048 struct dn_dev *dn_db = dev->dn_ptr; 1066 struct dn_dev *dn_db = rcu_dereference_raw(dev->dn_ptr);
1049 1067
1050 if (dn_db->parms.t2 > dn_db->parms.t3) 1068 if (dn_db->parms.t2 > dn_db->parms.t3)
1051 dn_db->parms.t2 = dn_db->parms.t3; 1069 dn_db->parms.t2 = dn_db->parms.t3;
@@ -1077,8 +1095,8 @@ static struct dn_dev *dn_dev_create(struct net_device *dev, int *err)
1077 return NULL; 1095 return NULL;
1078 1096
1079 memcpy(&dn_db->parms, p, sizeof(struct dn_dev_parms)); 1097 memcpy(&dn_db->parms, p, sizeof(struct dn_dev_parms));
1080 smp_wmb(); 1098
1081 dev->dn_ptr = dn_db; 1099 rcu_assign_pointer(dev->dn_ptr, dn_db);
1082 dn_db->dev = dev; 1100 dn_db->dev = dev;
1083 init_timer(&dn_db->timer); 1101 init_timer(&dn_db->timer);
1084 1102
@@ -1086,7 +1104,7 @@ static struct dn_dev *dn_dev_create(struct net_device *dev, int *err)
1086 1104
1087 dn_db->neigh_parms = neigh_parms_alloc(dev, &dn_neigh_table); 1105 dn_db->neigh_parms = neigh_parms_alloc(dev, &dn_neigh_table);
1088 if (!dn_db->neigh_parms) { 1106 if (!dn_db->neigh_parms) {
1089 dev->dn_ptr = NULL; 1107 rcu_assign_pointer(dev->dn_ptr, NULL);
1090 kfree(dn_db); 1108 kfree(dn_db);
1091 return NULL; 1109 return NULL;
1092 } 1110 }
@@ -1125,7 +1143,7 @@ void dn_dev_up(struct net_device *dev)
1125 struct dn_ifaddr *ifa; 1143 struct dn_ifaddr *ifa;
1126 __le16 addr = decnet_address; 1144 __le16 addr = decnet_address;
1127 int maybe_default = 0; 1145 int maybe_default = 0;
1128 struct dn_dev *dn_db = (struct dn_dev *)dev->dn_ptr; 1146 struct dn_dev *dn_db = rtnl_dereference(dev->dn_ptr);
1129 1147
1130 if ((dev->type != ARPHRD_ETHER) && (dev->type != ARPHRD_LOOPBACK)) 1148 if ((dev->type != ARPHRD_ETHER) && (dev->type != ARPHRD_LOOPBACK))
1131 return; 1149 return;
@@ -1176,7 +1194,7 @@ void dn_dev_up(struct net_device *dev)
1176 1194
1177static void dn_dev_delete(struct net_device *dev) 1195static void dn_dev_delete(struct net_device *dev)
1178{ 1196{
1179 struct dn_dev *dn_db = dev->dn_ptr; 1197 struct dn_dev *dn_db = rtnl_dereference(dev->dn_ptr);
1180 1198
1181 if (dn_db == NULL) 1199 if (dn_db == NULL)
1182 return; 1200 return;
@@ -1204,13 +1222,13 @@ static void dn_dev_delete(struct net_device *dev)
1204 1222
1205void dn_dev_down(struct net_device *dev) 1223void dn_dev_down(struct net_device *dev)
1206{ 1224{
1207 struct dn_dev *dn_db = dev->dn_ptr; 1225 struct dn_dev *dn_db = rtnl_dereference(dev->dn_ptr);
1208 struct dn_ifaddr *ifa; 1226 struct dn_ifaddr *ifa;
1209 1227
1210 if (dn_db == NULL) 1228 if (dn_db == NULL)
1211 return; 1229 return;
1212 1230
1213 while((ifa = dn_db->ifa_list) != NULL) { 1231 while ((ifa = rtnl_dereference(dn_db->ifa_list)) != NULL) {
1214 dn_dev_del_ifa(dn_db, &dn_db->ifa_list, 0); 1232 dn_dev_del_ifa(dn_db, &dn_db->ifa_list, 0);
1215 dn_dev_free_ifa(ifa); 1233 dn_dev_free_ifa(ifa);
1216 } 1234 }
@@ -1270,7 +1288,7 @@ static inline int is_dn_dev(struct net_device *dev)
1270} 1288}
1271 1289
1272static void *dn_dev_seq_start(struct seq_file *seq, loff_t *pos) 1290static void *dn_dev_seq_start(struct seq_file *seq, loff_t *pos)
1273 __acquires(rcu) 1291 __acquires(RCU)
1274{ 1292{
1275 int i; 1293 int i;
1276 struct net_device *dev; 1294 struct net_device *dev;
@@ -1313,7 +1331,7 @@ static void *dn_dev_seq_next(struct seq_file *seq, void *v, loff_t *pos)
1313} 1331}
1314 1332
1315static void dn_dev_seq_stop(struct seq_file *seq, void *v) 1333static void dn_dev_seq_stop(struct seq_file *seq, void *v)
1316 __releases(rcu) 1334 __releases(RCU)
1317{ 1335{
1318 rcu_read_unlock(); 1336 rcu_read_unlock();
1319} 1337}
@@ -1340,7 +1358,7 @@ static int dn_dev_seq_show(struct seq_file *seq, void *v)
1340 struct net_device *dev = v; 1358 struct net_device *dev = v;
1341 char peer_buf[DN_ASCBUF_LEN]; 1359 char peer_buf[DN_ASCBUF_LEN];
1342 char router_buf[DN_ASCBUF_LEN]; 1360 char router_buf[DN_ASCBUF_LEN];
1343 struct dn_dev *dn_db = dev->dn_ptr; 1361 struct dn_dev *dn_db = rcu_dereference(dev->dn_ptr);
1344 1362
1345 seq_printf(seq, "%-8s %1s %04u %04u %04lu %04lu" 1363 seq_printf(seq, "%-8s %1s %04u %04u %04lu %04lu"
1346 " %04hu %03d %02x %-10s %-7s %-7s\n", 1364 " %04hu %03d %02x %-10s %-7s %-7s\n",
diff --git a/net/decnet/dn_fib.c b/net/decnet/dn_fib.c
index 4ab96c15166..0ef0a81bcd7 100644
--- a/net/decnet/dn_fib.c
+++ b/net/decnet/dn_fib.c
@@ -610,10 +610,12 @@ static void dn_fib_del_ifaddr(struct dn_ifaddr *ifa)
610 /* Scan device list */ 610 /* Scan device list */
611 rcu_read_lock(); 611 rcu_read_lock();
612 for_each_netdev_rcu(&init_net, dev) { 612 for_each_netdev_rcu(&init_net, dev) {
613 dn_db = dev->dn_ptr; 613 dn_db = rcu_dereference(dev->dn_ptr);
614 if (dn_db == NULL) 614 if (dn_db == NULL)
615 continue; 615 continue;
616 for(ifa2 = dn_db->ifa_list; ifa2; ifa2 = ifa2->ifa_next) { 616 for (ifa2 = rcu_dereference(dn_db->ifa_list);
617 ifa2 != NULL;
618 ifa2 = rcu_dereference(ifa2->ifa_next)) {
617 if (ifa2->ifa_local == ifa->ifa_local) { 619 if (ifa2->ifa_local == ifa->ifa_local) {
618 found_it = 1; 620 found_it = 1;
619 break; 621 break;
diff --git a/net/decnet/dn_neigh.c b/net/decnet/dn_neigh.c
index a085dbcf5c7..602dade7e9a 100644
--- a/net/decnet/dn_neigh.c
+++ b/net/decnet/dn_neigh.c
@@ -391,7 +391,7 @@ int dn_neigh_router_hello(struct sk_buff *skb)
391 write_lock(&neigh->lock); 391 write_lock(&neigh->lock);
392 392
393 neigh->used = jiffies; 393 neigh->used = jiffies;
394 dn_db = (struct dn_dev *)neigh->dev->dn_ptr; 394 dn_db = rcu_dereference(neigh->dev->dn_ptr);
395 395
396 if (!(neigh->nud_state & NUD_PERMANENT)) { 396 if (!(neigh->nud_state & NUD_PERMANENT)) {
397 neigh->updated = jiffies; 397 neigh->updated = jiffies;
diff --git a/net/decnet/dn_route.c b/net/decnet/dn_route.c
index df0f3e54ff8..5e636365d33 100644
--- a/net/decnet/dn_route.c
+++ b/net/decnet/dn_route.c
@@ -93,7 +93,7 @@
93 93
94struct dn_rt_hash_bucket 94struct dn_rt_hash_bucket
95{ 95{
96 struct dn_route *chain; 96 struct dn_route __rcu *chain;
97 spinlock_t lock; 97 spinlock_t lock;
98}; 98};
99 99
@@ -110,6 +110,8 @@ static unsigned long dn_rt_deadline;
110 110
111static int dn_dst_gc(struct dst_ops *ops); 111static int dn_dst_gc(struct dst_ops *ops);
112static struct dst_entry *dn_dst_check(struct dst_entry *, __u32); 112static struct dst_entry *dn_dst_check(struct dst_entry *, __u32);
113static unsigned int dn_dst_default_advmss(const struct dst_entry *dst);
114static unsigned int dn_dst_default_mtu(const struct dst_entry *dst);
113static struct dst_entry *dn_dst_negative_advice(struct dst_entry *); 115static struct dst_entry *dn_dst_negative_advice(struct dst_entry *);
114static void dn_dst_link_failure(struct sk_buff *); 116static void dn_dst_link_failure(struct sk_buff *);
115static void dn_dst_update_pmtu(struct dst_entry *dst, u32 mtu); 117static void dn_dst_update_pmtu(struct dst_entry *dst, u32 mtu);
@@ -129,6 +131,8 @@ static struct dst_ops dn_dst_ops = {
129 .gc_thresh = 128, 131 .gc_thresh = 128,
130 .gc = dn_dst_gc, 132 .gc = dn_dst_gc,
131 .check = dn_dst_check, 133 .check = dn_dst_check,
134 .default_advmss = dn_dst_default_advmss,
135 .default_mtu = dn_dst_default_mtu,
132 .negative_advice = dn_dst_negative_advice, 136 .negative_advice = dn_dst_negative_advice,
133 .link_failure = dn_dst_link_failure, 137 .link_failure = dn_dst_link_failure,
134 .update_pmtu = dn_dst_update_pmtu, 138 .update_pmtu = dn_dst_update_pmtu,
@@ -157,15 +161,17 @@ static inline void dnrt_drop(struct dn_route *rt)
157static void dn_dst_check_expire(unsigned long dummy) 161static void dn_dst_check_expire(unsigned long dummy)
158{ 162{
159 int i; 163 int i;
160 struct dn_route *rt, **rtp; 164 struct dn_route *rt;
165 struct dn_route __rcu **rtp;
161 unsigned long now = jiffies; 166 unsigned long now = jiffies;
162 unsigned long expire = 120 * HZ; 167 unsigned long expire = 120 * HZ;
163 168
164 for(i = 0; i <= dn_rt_hash_mask; i++) { 169 for (i = 0; i <= dn_rt_hash_mask; i++) {
165 rtp = &dn_rt_hash_table[i].chain; 170 rtp = &dn_rt_hash_table[i].chain;
166 171
167 spin_lock(&dn_rt_hash_table[i].lock); 172 spin_lock(&dn_rt_hash_table[i].lock);
168 while((rt=*rtp) != NULL) { 173 while ((rt = rcu_dereference_protected(*rtp,
174 lockdep_is_held(&dn_rt_hash_table[i].lock))) != NULL) {
169 if (atomic_read(&rt->dst.__refcnt) || 175 if (atomic_read(&rt->dst.__refcnt) ||
170 (now - rt->dst.lastuse) < expire) { 176 (now - rt->dst.lastuse) < expire) {
171 rtp = &rt->dst.dn_next; 177 rtp = &rt->dst.dn_next;
@@ -186,17 +192,19 @@ static void dn_dst_check_expire(unsigned long dummy)
186 192
187static int dn_dst_gc(struct dst_ops *ops) 193static int dn_dst_gc(struct dst_ops *ops)
188{ 194{
189 struct dn_route *rt, **rtp; 195 struct dn_route *rt;
196 struct dn_route __rcu **rtp;
190 int i; 197 int i;
191 unsigned long now = jiffies; 198 unsigned long now = jiffies;
192 unsigned long expire = 10 * HZ; 199 unsigned long expire = 10 * HZ;
193 200
194 for(i = 0; i <= dn_rt_hash_mask; i++) { 201 for (i = 0; i <= dn_rt_hash_mask; i++) {
195 202
196 spin_lock_bh(&dn_rt_hash_table[i].lock); 203 spin_lock_bh(&dn_rt_hash_table[i].lock);
197 rtp = &dn_rt_hash_table[i].chain; 204 rtp = &dn_rt_hash_table[i].chain;
198 205
199 while((rt=*rtp) != NULL) { 206 while ((rt = rcu_dereference_protected(*rtp,
207 lockdep_is_held(&dn_rt_hash_table[i].lock))) != NULL) {
200 if (atomic_read(&rt->dst.__refcnt) || 208 if (atomic_read(&rt->dst.__refcnt) ||
201 (now - rt->dst.lastuse) < expire) { 209 (now - rt->dst.lastuse) < expire) {
202 rtp = &rt->dst.dn_next; 210 rtp = &rt->dst.dn_next;
@@ -227,7 +235,7 @@ static void dn_dst_update_pmtu(struct dst_entry *dst, u32 mtu)
227{ 235{
228 u32 min_mtu = 230; 236 u32 min_mtu = 230;
229 struct dn_dev *dn = dst->neighbour ? 237 struct dn_dev *dn = dst->neighbour ?
230 (struct dn_dev *)dst->neighbour->dev->dn_ptr : NULL; 238 rcu_dereference_raw(dst->neighbour->dev->dn_ptr) : NULL;
231 239
232 if (dn && dn->use_long == 0) 240 if (dn && dn->use_long == 0)
233 min_mtu -= 6; 241 min_mtu -= 6;
@@ -236,13 +244,14 @@ static void dn_dst_update_pmtu(struct dst_entry *dst, u32 mtu)
236 244
237 if (dst_metric(dst, RTAX_MTU) > mtu && mtu >= min_mtu) { 245 if (dst_metric(dst, RTAX_MTU) > mtu && mtu >= min_mtu) {
238 if (!(dst_metric_locked(dst, RTAX_MTU))) { 246 if (!(dst_metric_locked(dst, RTAX_MTU))) {
239 dst->metrics[RTAX_MTU-1] = mtu; 247 dst_metric_set(dst, RTAX_MTU, mtu);
240 dst_set_expires(dst, dn_rt_mtu_expires); 248 dst_set_expires(dst, dn_rt_mtu_expires);
241 } 249 }
242 if (!(dst_metric_locked(dst, RTAX_ADVMSS))) { 250 if (!(dst_metric_locked(dst, RTAX_ADVMSS))) {
243 u32 mss = mtu - DN_MAX_NSP_DATA_HEADER; 251 u32 mss = mtu - DN_MAX_NSP_DATA_HEADER;
244 if (dst_metric(dst, RTAX_ADVMSS) > mss) 252 u32 existing_mss = dst_metric_raw(dst, RTAX_ADVMSS);
245 dst->metrics[RTAX_ADVMSS-1] = mss; 253 if (!existing_mss || existing_mss > mss)
254 dst_metric_set(dst, RTAX_ADVMSS, mss);
246 } 255 }
247 } 256 }
248} 257}
@@ -267,23 +276,25 @@ static void dn_dst_link_failure(struct sk_buff *skb)
267 276
268static inline int compare_keys(struct flowi *fl1, struct flowi *fl2) 277static inline int compare_keys(struct flowi *fl1, struct flowi *fl2)
269{ 278{
270 return ((fl1->nl_u.dn_u.daddr ^ fl2->nl_u.dn_u.daddr) | 279 return ((fl1->fld_dst ^ fl2->fld_dst) |
271 (fl1->nl_u.dn_u.saddr ^ fl2->nl_u.dn_u.saddr) | 280 (fl1->fld_src ^ fl2->fld_src) |
272 (fl1->mark ^ fl2->mark) | 281 (fl1->mark ^ fl2->mark) |
273 (fl1->nl_u.dn_u.scope ^ fl2->nl_u.dn_u.scope) | 282 (fl1->fld_scope ^ fl2->fld_scope) |
274 (fl1->oif ^ fl2->oif) | 283 (fl1->oif ^ fl2->oif) |
275 (fl1->iif ^ fl2->iif)) == 0; 284 (fl1->iif ^ fl2->iif)) == 0;
276} 285}
277 286
278static int dn_insert_route(struct dn_route *rt, unsigned hash, struct dn_route **rp) 287static int dn_insert_route(struct dn_route *rt, unsigned hash, struct dn_route **rp)
279{ 288{
280 struct dn_route *rth, **rthp; 289 struct dn_route *rth;
290 struct dn_route __rcu **rthp;
281 unsigned long now = jiffies; 291 unsigned long now = jiffies;
282 292
283 rthp = &dn_rt_hash_table[hash].chain; 293 rthp = &dn_rt_hash_table[hash].chain;
284 294
285 spin_lock_bh(&dn_rt_hash_table[hash].lock); 295 spin_lock_bh(&dn_rt_hash_table[hash].lock);
286 while((rth = *rthp) != NULL) { 296 while ((rth = rcu_dereference_protected(*rthp,
297 lockdep_is_held(&dn_rt_hash_table[hash].lock))) != NULL) {
287 if (compare_keys(&rth->fl, &rt->fl)) { 298 if (compare_keys(&rth->fl, &rt->fl)) {
288 /* Put it first */ 299 /* Put it first */
289 *rthp = rth->dst.dn_next; 300 *rthp = rth->dst.dn_next;
@@ -315,15 +326,15 @@ static void dn_run_flush(unsigned long dummy)
315 int i; 326 int i;
316 struct dn_route *rt, *next; 327 struct dn_route *rt, *next;
317 328
318 for(i = 0; i < dn_rt_hash_mask; i++) { 329 for (i = 0; i < dn_rt_hash_mask; i++) {
319 spin_lock_bh(&dn_rt_hash_table[i].lock); 330 spin_lock_bh(&dn_rt_hash_table[i].lock);
320 331
321 if ((rt = xchg(&dn_rt_hash_table[i].chain, NULL)) == NULL) 332 if ((rt = xchg((struct dn_route **)&dn_rt_hash_table[i].chain, NULL)) == NULL)
322 goto nothing_to_declare; 333 goto nothing_to_declare;
323 334
324 for(; rt; rt=next) { 335 for(; rt; rt = next) {
325 next = rt->dst.dn_next; 336 next = rcu_dereference_raw(rt->dst.dn_next);
326 rt->dst.dn_next = NULL; 337 RCU_INIT_POINTER(rt->dst.dn_next, NULL);
327 dst_free((struct dst_entry *)rt); 338 dst_free((struct dst_entry *)rt);
328 } 339 }
329 340
@@ -458,15 +469,16 @@ static int dn_return_long(struct sk_buff *skb)
458 */ 469 */
459static int dn_route_rx_packet(struct sk_buff *skb) 470static int dn_route_rx_packet(struct sk_buff *skb)
460{ 471{
461 struct dn_skb_cb *cb = DN_SKB_CB(skb); 472 struct dn_skb_cb *cb;
462 int err; 473 int err;
463 474
464 if ((err = dn_route_input(skb)) == 0) 475 if ((err = dn_route_input(skb)) == 0)
465 return dst_input(skb); 476 return dst_input(skb);
466 477
478 cb = DN_SKB_CB(skb);
467 if (decnet_debug_level & 4) { 479 if (decnet_debug_level & 4) {
468 char *devname = skb->dev ? skb->dev->name : "???"; 480 char *devname = skb->dev ? skb->dev->name : "???";
469 struct dn_skb_cb *cb = DN_SKB_CB(skb); 481
470 printk(KERN_DEBUG 482 printk(KERN_DEBUG
471 "DECnet: dn_route_rx_packet: rt_flags=0x%02x dev=%s len=%d src=0x%04hx dst=0x%04hx err=%d type=%d\n", 483 "DECnet: dn_route_rx_packet: rt_flags=0x%02x dev=%s len=%d src=0x%04hx dst=0x%04hx err=%d type=%d\n",
472 (int)cb->rt_flags, devname, skb->len, 484 (int)cb->rt_flags, devname, skb->len,
@@ -573,7 +585,7 @@ int dn_route_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type
573 struct dn_skb_cb *cb; 585 struct dn_skb_cb *cb;
574 unsigned char flags = 0; 586 unsigned char flags = 0;
575 __u16 len = le16_to_cpu(*(__le16 *)skb->data); 587 __u16 len = le16_to_cpu(*(__le16 *)skb->data);
576 struct dn_dev *dn = (struct dn_dev *)dev->dn_ptr; 588 struct dn_dev *dn = rcu_dereference(dev->dn_ptr);
577 unsigned char padlen = 0; 589 unsigned char padlen = 0;
578 590
579 if (!net_eq(dev_net(dev), &init_net)) 591 if (!net_eq(dev_net(dev), &init_net))
@@ -728,7 +740,7 @@ static int dn_forward(struct sk_buff *skb)
728{ 740{
729 struct dn_skb_cb *cb = DN_SKB_CB(skb); 741 struct dn_skb_cb *cb = DN_SKB_CB(skb);
730 struct dst_entry *dst = skb_dst(skb); 742 struct dst_entry *dst = skb_dst(skb);
731 struct dn_dev *dn_db = dst->dev->dn_ptr; 743 struct dn_dev *dn_db = rcu_dereference(dst->dev->dn_ptr);
732 struct dn_route *rt; 744 struct dn_route *rt;
733 struct neighbour *neigh = dst->neighbour; 745 struct neighbour *neigh = dst->neighbour;
734 int header_len; 746 int header_len;
@@ -788,19 +800,28 @@ static int dn_rt_bug(struct sk_buff *skb)
788 return NET_RX_DROP; 800 return NET_RX_DROP;
789} 801}
790 802
803static unsigned int dn_dst_default_advmss(const struct dst_entry *dst)
804{
805 return dn_mss_from_pmtu(dst->dev, dst_mtu(dst));
806}
807
808static unsigned int dn_dst_default_mtu(const struct dst_entry *dst)
809{
810 return dst->dev->mtu;
811}
812
791static int dn_rt_set_next_hop(struct dn_route *rt, struct dn_fib_res *res) 813static int dn_rt_set_next_hop(struct dn_route *rt, struct dn_fib_res *res)
792{ 814{
793 struct dn_fib_info *fi = res->fi; 815 struct dn_fib_info *fi = res->fi;
794 struct net_device *dev = rt->dst.dev; 816 struct net_device *dev = rt->dst.dev;
795 struct neighbour *n; 817 struct neighbour *n;
796 unsigned mss; 818 unsigned int metric;
797 819
798 if (fi) { 820 if (fi) {
799 if (DN_FIB_RES_GW(*res) && 821 if (DN_FIB_RES_GW(*res) &&
800 DN_FIB_RES_NH(*res).nh_scope == RT_SCOPE_LINK) 822 DN_FIB_RES_NH(*res).nh_scope == RT_SCOPE_LINK)
801 rt->rt_gateway = DN_FIB_RES_GW(*res); 823 rt->rt_gateway = DN_FIB_RES_GW(*res);
802 memcpy(rt->dst.metrics, fi->fib_metrics, 824 dst_import_metrics(&rt->dst, fi->fib_metrics);
803 sizeof(rt->dst.metrics));
804 } 825 }
805 rt->rt_type = res->type; 826 rt->rt_type = res->type;
806 827
@@ -811,13 +832,14 @@ static int dn_rt_set_next_hop(struct dn_route *rt, struct dn_fib_res *res)
811 rt->dst.neighbour = n; 832 rt->dst.neighbour = n;
812 } 833 }
813 834
814 if (dst_metric(&rt->dst, RTAX_MTU) == 0 || 835 if (dst_metric(&rt->dst, RTAX_MTU) > rt->dst.dev->mtu)
815 dst_metric(&rt->dst, RTAX_MTU) > rt->dst.dev->mtu) 836 dst_metric_set(&rt->dst, RTAX_MTU, rt->dst.dev->mtu);
816 rt->dst.metrics[RTAX_MTU-1] = rt->dst.dev->mtu; 837 metric = dst_metric_raw(&rt->dst, RTAX_ADVMSS);
817 mss = dn_mss_from_pmtu(dev, dst_mtu(&rt->dst)); 838 if (metric) {
818 if (dst_metric(&rt->dst, RTAX_ADVMSS) == 0 || 839 unsigned int mss = dn_mss_from_pmtu(dev, dst_mtu(&rt->dst));
819 dst_metric(&rt->dst, RTAX_ADVMSS) > mss) 840 if (metric > mss)
820 rt->dst.metrics[RTAX_ADVMSS-1] = mss; 841 dst_metric_set(&rt->dst, RTAX_ADVMSS, mss);
842 }
821 return 0; 843 return 0;
822} 844}
823 845
@@ -835,13 +857,16 @@ static inline int dn_match_addr(__le16 addr1, __le16 addr2)
835static __le16 dnet_select_source(const struct net_device *dev, __le16 daddr, int scope) 857static __le16 dnet_select_source(const struct net_device *dev, __le16 daddr, int scope)
836{ 858{
837 __le16 saddr = 0; 859 __le16 saddr = 0;
838 struct dn_dev *dn_db = dev->dn_ptr; 860 struct dn_dev *dn_db;
839 struct dn_ifaddr *ifa; 861 struct dn_ifaddr *ifa;
840 int best_match = 0; 862 int best_match = 0;
841 int ret; 863 int ret;
842 864
843 read_lock(&dev_base_lock); 865 rcu_read_lock();
844 for(ifa = dn_db->ifa_list; ifa; ifa = ifa->ifa_next) { 866 dn_db = rcu_dereference(dev->dn_ptr);
867 for (ifa = rcu_dereference(dn_db->ifa_list);
868 ifa != NULL;
869 ifa = rcu_dereference(ifa->ifa_next)) {
845 if (ifa->ifa_scope > scope) 870 if (ifa->ifa_scope > scope)
846 continue; 871 continue;
847 if (!daddr) { 872 if (!daddr) {
@@ -854,7 +879,7 @@ static __le16 dnet_select_source(const struct net_device *dev, __le16 daddr, int
854 if (best_match == 0) 879 if (best_match == 0)
855 saddr = ifa->ifa_local; 880 saddr = ifa->ifa_local;
856 } 881 }
857 read_unlock(&dev_base_lock); 882 rcu_read_unlock();
858 883
859 return saddr; 884 return saddr;
860} 885}
@@ -872,11 +897,9 @@ static inline __le16 dn_fib_rules_map_destination(__le16 daddr, struct dn_fib_re
872 897
873static int dn_route_output_slow(struct dst_entry **pprt, const struct flowi *oldflp, int try_hard) 898static int dn_route_output_slow(struct dst_entry **pprt, const struct flowi *oldflp, int try_hard)
874{ 899{
875 struct flowi fl = { .nl_u = { .dn_u = 900 struct flowi fl = { .fld_dst = oldflp->fld_dst,
876 { .daddr = oldflp->fld_dst, 901 .fld_src = oldflp->fld_src,
877 .saddr = oldflp->fld_src, 902 .fld_scope = RT_SCOPE_UNIVERSE,
878 .scope = RT_SCOPE_UNIVERSE,
879 } },
880 .mark = oldflp->mark, 903 .mark = oldflp->mark,
881 .iif = init_net.loopback_dev->ifindex, 904 .iif = init_net.loopback_dev->ifindex,
882 .oif = oldflp->oif }; 905 .oif = oldflp->oif };
@@ -1020,7 +1043,7 @@ source_ok:
1020 err = -ENODEV; 1043 err = -ENODEV;
1021 if (dev_out == NULL) 1044 if (dev_out == NULL)
1022 goto out; 1045 goto out;
1023 dn_db = dev_out->dn_ptr; 1046 dn_db = rcu_dereference_raw(dev_out->dn_ptr);
1024 /* Possible improvement - check all devices for local addr */ 1047 /* Possible improvement - check all devices for local addr */
1025 if (dn_dev_islocal(dev_out, fl.fld_dst)) { 1048 if (dn_dev_islocal(dev_out, fl.fld_dst)) {
1026 dev_put(dev_out); 1049 dev_put(dev_out);
@@ -1171,7 +1194,7 @@ static int __dn_route_output_key(struct dst_entry **pprt, const struct flowi *fl
1171 if ((flp->fld_dst == rt->fl.fld_dst) && 1194 if ((flp->fld_dst == rt->fl.fld_dst) &&
1172 (flp->fld_src == rt->fl.fld_src) && 1195 (flp->fld_src == rt->fl.fld_src) &&
1173 (flp->mark == rt->fl.mark) && 1196 (flp->mark == rt->fl.mark) &&
1174 (rt->fl.iif == 0) && 1197 dn_is_output_route(rt) &&
1175 (rt->fl.oif == flp->oif)) { 1198 (rt->fl.oif == flp->oif)) {
1176 dst_use(&rt->dst, jiffies); 1199 dst_use(&rt->dst, jiffies);
1177 rcu_read_unlock_bh(); 1200 rcu_read_unlock_bh();
@@ -1220,11 +1243,9 @@ static int dn_route_input_slow(struct sk_buff *skb)
1220 int flags = 0; 1243 int flags = 0;
1221 __le16 gateway = 0; 1244 __le16 gateway = 0;
1222 __le16 local_src = 0; 1245 __le16 local_src = 0;
1223 struct flowi fl = { .nl_u = { .dn_u = 1246 struct flowi fl = { .fld_dst = cb->dst,
1224 { .daddr = cb->dst, 1247 .fld_src = cb->src,
1225 .saddr = cb->src, 1248 .fld_scope = RT_SCOPE_UNIVERSE,
1226 .scope = RT_SCOPE_UNIVERSE,
1227 } },
1228 .mark = skb->mark, 1249 .mark = skb->mark,
1229 .iif = skb->dev->ifindex }; 1250 .iif = skb->dev->ifindex };
1230 struct dn_fib_res res = { .fi = NULL, .type = RTN_UNREACHABLE }; 1251 struct dn_fib_res res = { .fi = NULL, .type = RTN_UNREACHABLE };
@@ -1233,7 +1254,7 @@ static int dn_route_input_slow(struct sk_buff *skb)
1233 1254
1234 dev_hold(in_dev); 1255 dev_hold(in_dev);
1235 1256
1236 if ((dn_db = in_dev->dn_ptr) == NULL) 1257 if ((dn_db = rcu_dereference(in_dev->dn_ptr)) == NULL)
1237 goto out; 1258 goto out;
1238 1259
1239 /* Zero source addresses are not allowed */ 1260 /* Zero source addresses are not allowed */
@@ -1496,13 +1517,13 @@ static int dn_rt_fill_info(struct sk_buff *skb, u32 pid, u32 seq,
1496 RTA_PUT(skb, RTA_PREFSRC, 2, &rt->rt_local_src); 1517 RTA_PUT(skb, RTA_PREFSRC, 2, &rt->rt_local_src);
1497 if (rt->rt_daddr != rt->rt_gateway) 1518 if (rt->rt_daddr != rt->rt_gateway)
1498 RTA_PUT(skb, RTA_GATEWAY, 2, &rt->rt_gateway); 1519 RTA_PUT(skb, RTA_GATEWAY, 2, &rt->rt_gateway);
1499 if (rtnetlink_put_metrics(skb, rt->dst.metrics) < 0) 1520 if (rtnetlink_put_metrics(skb, dst_metrics_ptr(&rt->dst)) < 0)
1500 goto rtattr_failure; 1521 goto rtattr_failure;
1501 expires = rt->dst.expires ? rt->dst.expires - jiffies : 0; 1522 expires = rt->dst.expires ? rt->dst.expires - jiffies : 0;
1502 if (rtnl_put_cacheinfo(skb, &rt->dst, 0, 0, 0, expires, 1523 if (rtnl_put_cacheinfo(skb, &rt->dst, 0, 0, 0, expires,
1503 rt->dst.error) < 0) 1524 rt->dst.error) < 0)
1504 goto rtattr_failure; 1525 goto rtattr_failure;
1505 if (rt->fl.iif) 1526 if (dn_is_input_route(rt))
1506 RTA_PUT(skb, RTA_IIF, sizeof(int), &rt->fl.iif); 1527 RTA_PUT(skb, RTA_IIF, sizeof(int), &rt->fl.iif);
1507 1528
1508 nlh->nlmsg_len = skb_tail_pointer(skb) - b; 1529 nlh->nlmsg_len = skb_tail_pointer(skb) - b;
@@ -1677,15 +1698,15 @@ static struct dn_route *dn_rt_cache_get_next(struct seq_file *seq, struct dn_rou
1677{ 1698{
1678 struct dn_rt_cache_iter_state *s = seq->private; 1699 struct dn_rt_cache_iter_state *s = seq->private;
1679 1700
1680 rt = rt->dst.dn_next; 1701 rt = rcu_dereference_bh(rt->dst.dn_next);
1681 while(!rt) { 1702 while (!rt) {
1682 rcu_read_unlock_bh(); 1703 rcu_read_unlock_bh();
1683 if (--s->bucket < 0) 1704 if (--s->bucket < 0)
1684 break; 1705 break;
1685 rcu_read_lock_bh(); 1706 rcu_read_lock_bh();
1686 rt = dn_rt_hash_table[s->bucket].chain; 1707 rt = rcu_dereference_bh(dn_rt_hash_table[s->bucket].chain);
1687 } 1708 }
1688 return rcu_dereference_bh(rt); 1709 return rt;
1689} 1710}
1690 1711
1691static void *dn_rt_cache_seq_start(struct seq_file *seq, loff_t *pos) 1712static void *dn_rt_cache_seq_start(struct seq_file *seq, loff_t *pos)
diff --git a/net/decnet/dn_rules.c b/net/decnet/dn_rules.c
index 48fdf10be7a..6eb91df3c55 100644
--- a/net/decnet/dn_rules.c
+++ b/net/decnet/dn_rules.c
@@ -175,7 +175,7 @@ static int dn_fib_rule_compare(struct fib_rule *rule, struct fib_rule_hdr *frh,
175 175
176unsigned dnet_addr_type(__le16 addr) 176unsigned dnet_addr_type(__le16 addr)
177{ 177{
178 struct flowi fl = { .nl_u = { .dn_u = { .daddr = addr } } }; 178 struct flowi fl = { .fld_dst = addr };
179 struct dn_fib_res res; 179 struct dn_fib_res res;
180 unsigned ret = RTN_UNICAST; 180 unsigned ret = RTN_UNICAST;
181 struct dn_fib_table *tb = dn_fib_get_table(RT_TABLE_LOCAL, 0); 181 struct dn_fib_table *tb = dn_fib_get_table(RT_TABLE_LOCAL, 0);