aboutsummaryrefslogtreecommitdiffstats
path: root/net/decnet/dn_route.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/decnet/dn_route.c')
-rw-r--r--net/decnet/dn_route.c143
1 files changed, 80 insertions, 63 deletions
diff --git a/net/decnet/dn_route.c b/net/decnet/dn_route.c
index 74544bc6fde..43450c10022 100644
--- a/net/decnet/dn_route.c
+++ b/net/decnet/dn_route.c
@@ -116,6 +116,7 @@ static void dn_dst_destroy(struct dst_entry *);
116static struct dst_entry *dn_dst_negative_advice(struct dst_entry *); 116static struct dst_entry *dn_dst_negative_advice(struct dst_entry *);
117static void dn_dst_link_failure(struct sk_buff *); 117static void dn_dst_link_failure(struct sk_buff *);
118static void dn_dst_update_pmtu(struct dst_entry *dst, u32 mtu); 118static void dn_dst_update_pmtu(struct dst_entry *dst, u32 mtu);
119static struct neighbour *dn_dst_neigh_lookup(const struct dst_entry *dst, const void *daddr);
119static int dn_route_input(struct sk_buff *); 120static int dn_route_input(struct sk_buff *);
120static void dn_run_flush(unsigned long dummy); 121static void dn_run_flush(unsigned long dummy);
121 122
@@ -139,6 +140,7 @@ static struct dst_ops dn_dst_ops = {
139 .negative_advice = dn_dst_negative_advice, 140 .negative_advice = dn_dst_negative_advice,
140 .link_failure = dn_dst_link_failure, 141 .link_failure = dn_dst_link_failure,
141 .update_pmtu = dn_dst_update_pmtu, 142 .update_pmtu = dn_dst_update_pmtu,
143 .neigh_lookup = dn_dst_neigh_lookup,
142}; 144};
143 145
144static void dn_dst_destroy(struct dst_entry *dst) 146static void dn_dst_destroy(struct dst_entry *dst)
@@ -241,9 +243,11 @@ static int dn_dst_gc(struct dst_ops *ops)
241 */ 243 */
242static void dn_dst_update_pmtu(struct dst_entry *dst, u32 mtu) 244static void dn_dst_update_pmtu(struct dst_entry *dst, u32 mtu)
243{ 245{
246 struct neighbour *n = dst_get_neighbour(dst);
244 u32 min_mtu = 230; 247 u32 min_mtu = 230;
245 struct dn_dev *dn = dst->neighbour ? 248 struct dn_dev *dn;
246 rcu_dereference_raw(dst->neighbour->dev->dn_ptr) : NULL; 249
250 dn = n ? rcu_dereference_raw(n->dev->dn_ptr) : NULL;
247 251
248 if (dn && dn->use_long == 0) 252 if (dn && dn->use_long == 0)
249 min_mtu -= 6; 253 min_mtu -= 6;
@@ -495,11 +499,11 @@ static int dn_route_rx_packet(struct sk_buff *skb)
495 } 499 }
496 500
497 if ((skb->pkt_type == PACKET_HOST) && (cb->rt_flags & DN_RT_F_RQR)) { 501 if ((skb->pkt_type == PACKET_HOST) && (cb->rt_flags & DN_RT_F_RQR)) {
498 switch(cb->rt_flags & DN_RT_PKT_MSK) { 502 switch (cb->rt_flags & DN_RT_PKT_MSK) {
499 case DN_RT_PKT_SHORT: 503 case DN_RT_PKT_SHORT:
500 return dn_return_short(skb); 504 return dn_return_short(skb);
501 case DN_RT_PKT_LONG: 505 case DN_RT_PKT_LONG:
502 return dn_return_long(skb); 506 return dn_return_long(skb);
503 } 507 }
504 } 508 }
505 509
@@ -652,38 +656,38 @@ int dn_route_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type
652 if (unlikely(skb_linearize(skb))) 656 if (unlikely(skb_linearize(skb)))
653 goto dump_it; 657 goto dump_it;
654 658
655 switch(flags & DN_RT_CNTL_MSK) { 659 switch (flags & DN_RT_CNTL_MSK) {
656 case DN_RT_PKT_INIT: 660 case DN_RT_PKT_INIT:
657 dn_dev_init_pkt(skb); 661 dn_dev_init_pkt(skb);
658 break; 662 break;
659 case DN_RT_PKT_VERI: 663 case DN_RT_PKT_VERI:
660 dn_dev_veri_pkt(skb); 664 dn_dev_veri_pkt(skb);
661 break; 665 break;
662 } 666 }
663 667
664 if (dn->parms.state != DN_DEV_S_RU) 668 if (dn->parms.state != DN_DEV_S_RU)
665 goto dump_it; 669 goto dump_it;
666 670
667 switch(flags & DN_RT_CNTL_MSK) { 671 switch (flags & DN_RT_CNTL_MSK) {
668 case DN_RT_PKT_HELO: 672 case DN_RT_PKT_HELO:
669 return NF_HOOK(NFPROTO_DECNET, NF_DN_HELLO, 673 return NF_HOOK(NFPROTO_DECNET, NF_DN_HELLO,
670 skb, skb->dev, NULL, 674 skb, skb->dev, NULL,
671 dn_route_ptp_hello); 675 dn_route_ptp_hello);
672 676
673 case DN_RT_PKT_L1RT: 677 case DN_RT_PKT_L1RT:
674 case DN_RT_PKT_L2RT: 678 case DN_RT_PKT_L2RT:
675 return NF_HOOK(NFPROTO_DECNET, NF_DN_ROUTE, 679 return NF_HOOK(NFPROTO_DECNET, NF_DN_ROUTE,
676 skb, skb->dev, NULL, 680 skb, skb->dev, NULL,
677 dn_route_discard); 681 dn_route_discard);
678 case DN_RT_PKT_ERTH: 682 case DN_RT_PKT_ERTH:
679 return NF_HOOK(NFPROTO_DECNET, NF_DN_HELLO, 683 return NF_HOOK(NFPROTO_DECNET, NF_DN_HELLO,
680 skb, skb->dev, NULL, 684 skb, skb->dev, NULL,
681 dn_neigh_router_hello); 685 dn_neigh_router_hello);
682 686
683 case DN_RT_PKT_EEDH: 687 case DN_RT_PKT_EEDH:
684 return NF_HOOK(NFPROTO_DECNET, NF_DN_HELLO, 688 return NF_HOOK(NFPROTO_DECNET, NF_DN_HELLO,
685 skb, skb->dev, NULL, 689 skb, skb->dev, NULL,
686 dn_neigh_endnode_hello); 690 dn_neigh_endnode_hello);
687 } 691 }
688 } else { 692 } else {
689 if (dn->parms.state != DN_DEV_S_RU) 693 if (dn->parms.state != DN_DEV_S_RU)
@@ -691,11 +695,11 @@ int dn_route_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type
691 695
692 skb_pull(skb, 1); /* Pull flags */ 696 skb_pull(skb, 1); /* Pull flags */
693 697
694 switch(flags & DN_RT_PKT_MSK) { 698 switch (flags & DN_RT_PKT_MSK) {
695 case DN_RT_PKT_LONG: 699 case DN_RT_PKT_LONG:
696 return dn_route_rx_long(skb); 700 return dn_route_rx_long(skb);
697 case DN_RT_PKT_SHORT: 701 case DN_RT_PKT_SHORT:
698 return dn_route_rx_short(skb); 702 return dn_route_rx_short(skb);
699 } 703 }
700 } 704 }
701 705
@@ -705,6 +709,14 @@ out:
705 return NET_RX_DROP; 709 return NET_RX_DROP;
706} 710}
707 711
712static int dn_to_neigh_output(struct sk_buff *skb)
713{
714 struct dst_entry *dst = skb_dst(skb);
715 struct neighbour *n = dst_get_neighbour(dst);
716
717 return n->output(n, skb);
718}
719
708static int dn_output(struct sk_buff *skb) 720static int dn_output(struct sk_buff *skb)
709{ 721{
710 struct dst_entry *dst = skb_dst(skb); 722 struct dst_entry *dst = skb_dst(skb);
@@ -715,7 +727,7 @@ static int dn_output(struct sk_buff *skb)
715 727
716 int err = -EINVAL; 728 int err = -EINVAL;
717 729
718 if ((neigh = dst->neighbour) == NULL) 730 if ((neigh = dst_get_neighbour(dst)) == NULL)
719 goto error; 731 goto error;
720 732
721 skb->dev = dev; 733 skb->dev = dev;
@@ -733,7 +745,7 @@ static int dn_output(struct sk_buff *skb)
733 cb->hops = 0; 745 cb->hops = 0;
734 746
735 return NF_HOOK(NFPROTO_DECNET, NF_DN_LOCAL_OUT, skb, NULL, dev, 747 return NF_HOOK(NFPROTO_DECNET, NF_DN_LOCAL_OUT, skb, NULL, dev,
736 neigh->output); 748 dn_to_neigh_output);
737 749
738error: 750error:
739 if (net_ratelimit()) 751 if (net_ratelimit())
@@ -750,7 +762,6 @@ static int dn_forward(struct sk_buff *skb)
750 struct dst_entry *dst = skb_dst(skb); 762 struct dst_entry *dst = skb_dst(skb);
751 struct dn_dev *dn_db = rcu_dereference(dst->dev->dn_ptr); 763 struct dn_dev *dn_db = rcu_dereference(dst->dev->dn_ptr);
752 struct dn_route *rt; 764 struct dn_route *rt;
753 struct neighbour *neigh = dst->neighbour;
754 int header_len; 765 int header_len;
755#ifdef CONFIG_NETFILTER 766#ifdef CONFIG_NETFILTER
756 struct net_device *dev = skb->dev; 767 struct net_device *dev = skb->dev;
@@ -783,7 +794,7 @@ static int dn_forward(struct sk_buff *skb)
783 cb->rt_flags |= DN_RT_F_IE; 794 cb->rt_flags |= DN_RT_F_IE;
784 795
785 return NF_HOOK(NFPROTO_DECNET, NF_DN_FORWARD, skb, dev, skb->dev, 796 return NF_HOOK(NFPROTO_DECNET, NF_DN_FORWARD, skb, dev, skb->dev,
786 neigh->output); 797 dn_to_neigh_output);
787 798
788drop: 799drop:
789 kfree_skb(skb); 800 kfree_skb(skb);
@@ -818,6 +829,11 @@ static unsigned int dn_dst_default_mtu(const struct dst_entry *dst)
818 return dst->dev->mtu; 829 return dst->dev->mtu;
819} 830}
820 831
832static struct neighbour *dn_dst_neigh_lookup(const struct dst_entry *dst, const void *daddr)
833{
834 return __neigh_lookup_errno(&dn_neigh_table, daddr, dst->dev);
835}
836
821static int dn_rt_set_next_hop(struct dn_route *rt, struct dn_fib_res *res) 837static int dn_rt_set_next_hop(struct dn_route *rt, struct dn_fib_res *res)
822{ 838{
823 struct dn_fib_info *fi = res->fi; 839 struct dn_fib_info *fi = res->fi;
@@ -833,11 +849,11 @@ static int dn_rt_set_next_hop(struct dn_route *rt, struct dn_fib_res *res)
833 } 849 }
834 rt->rt_type = res->type; 850 rt->rt_type = res->type;
835 851
836 if (dev != NULL && rt->dst.neighbour == NULL) { 852 if (dev != NULL && dst_get_neighbour(&rt->dst) == NULL) {
837 n = __neigh_lookup_errno(&dn_neigh_table, &rt->rt_gateway, dev); 853 n = __neigh_lookup_errno(&dn_neigh_table, &rt->rt_gateway, dev);
838 if (IS_ERR(n)) 854 if (IS_ERR(n))
839 return PTR_ERR(n); 855 return PTR_ERR(n);
840 rt->dst.neighbour = n; 856 dst_set_neighbour(&rt->dst, n);
841 } 857 }
842 858
843 if (dst_metric(&rt->dst, RTAX_MTU) > rt->dst.dev->mtu) 859 if (dst_metric(&rt->dst, RTAX_MTU) > rt->dst.dev->mtu)
@@ -1144,7 +1160,7 @@ make_route:
1144 rt->rt_dst_map = fld.daddr; 1160 rt->rt_dst_map = fld.daddr;
1145 rt->rt_src_map = fld.saddr; 1161 rt->rt_src_map = fld.saddr;
1146 1162
1147 rt->dst.neighbour = neigh; 1163 dst_set_neighbour(&rt->dst, neigh);
1148 neigh = NULL; 1164 neigh = NULL;
1149 1165
1150 rt->dst.lastuse = jiffies; 1166 rt->dst.lastuse = jiffies;
@@ -1416,23 +1432,23 @@ make_route:
1416 rt->fld.flowidn_iif = in_dev->ifindex; 1432 rt->fld.flowidn_iif = in_dev->ifindex;
1417 rt->fld.flowidn_mark = fld.flowidn_mark; 1433 rt->fld.flowidn_mark = fld.flowidn_mark;
1418 1434
1419 rt->dst.neighbour = neigh; 1435 dst_set_neighbour(&rt->dst, neigh);
1420 rt->dst.lastuse = jiffies; 1436 rt->dst.lastuse = jiffies;
1421 rt->dst.output = dn_rt_bug; 1437 rt->dst.output = dn_rt_bug;
1422 switch(res.type) { 1438 switch (res.type) {
1423 case RTN_UNICAST: 1439 case RTN_UNICAST:
1424 rt->dst.input = dn_forward; 1440 rt->dst.input = dn_forward;
1425 break; 1441 break;
1426 case RTN_LOCAL: 1442 case RTN_LOCAL:
1427 rt->dst.output = dn_output; 1443 rt->dst.output = dn_output;
1428 rt->dst.input = dn_nsp_rx; 1444 rt->dst.input = dn_nsp_rx;
1429 rt->dst.dev = in_dev; 1445 rt->dst.dev = in_dev;
1430 flags |= RTCF_LOCAL; 1446 flags |= RTCF_LOCAL;
1431 break; 1447 break;
1432 default: 1448 default:
1433 case RTN_UNREACHABLE: 1449 case RTN_UNREACHABLE:
1434 case RTN_BLACKHOLE: 1450 case RTN_BLACKHOLE:
1435 rt->dst.input = dst_discard; 1451 rt->dst.input = dst_discard;
1436 } 1452 }
1437 rt->rt_flags = flags; 1453 rt->rt_flags = flags;
1438 1454
@@ -1841,10 +1857,11 @@ void __init dn_route_init(void)
1841 proc_net_fops_create(&init_net, "decnet_cache", S_IRUGO, &dn_rt_cache_seq_fops); 1857 proc_net_fops_create(&init_net, "decnet_cache", S_IRUGO, &dn_rt_cache_seq_fops);
1842 1858
1843#ifdef CONFIG_DECNET_ROUTER 1859#ifdef CONFIG_DECNET_ROUTER
1844 rtnl_register(PF_DECnet, RTM_GETROUTE, dn_cache_getroute, dn_fib_dump); 1860 rtnl_register(PF_DECnet, RTM_GETROUTE, dn_cache_getroute,
1861 dn_fib_dump, NULL);
1845#else 1862#else
1846 rtnl_register(PF_DECnet, RTM_GETROUTE, dn_cache_getroute, 1863 rtnl_register(PF_DECnet, RTM_GETROUTE, dn_cache_getroute,
1847 dn_cache_dump); 1864 dn_cache_dump, NULL);
1848#endif 1865#endif
1849} 1866}
1850 1867