diff options
Diffstat (limited to 'net/decnet/dn_route.c')
-rw-r--r-- | net/decnet/dn_route.c | 143 |
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 *); | |||
116 | static struct dst_entry *dn_dst_negative_advice(struct dst_entry *); | 116 | static struct dst_entry *dn_dst_negative_advice(struct dst_entry *); |
117 | static void dn_dst_link_failure(struct sk_buff *); | 117 | static void dn_dst_link_failure(struct sk_buff *); |
118 | static void dn_dst_update_pmtu(struct dst_entry *dst, u32 mtu); | 118 | static void dn_dst_update_pmtu(struct dst_entry *dst, u32 mtu); |
119 | static struct neighbour *dn_dst_neigh_lookup(const struct dst_entry *dst, const void *daddr); | ||
119 | static int dn_route_input(struct sk_buff *); | 120 | static int dn_route_input(struct sk_buff *); |
120 | static void dn_run_flush(unsigned long dummy); | 121 | static 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 | ||
144 | static void dn_dst_destroy(struct dst_entry *dst) | 146 | static void dn_dst_destroy(struct dst_entry *dst) |
@@ -241,9 +243,11 @@ static int dn_dst_gc(struct dst_ops *ops) | |||
241 | */ | 243 | */ |
242 | static void dn_dst_update_pmtu(struct dst_entry *dst, u32 mtu) | 244 | static 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 | ||
712 | static 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 | |||
708 | static int dn_output(struct sk_buff *skb) | 720 | static 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 | ||
738 | error: | 750 | error: |
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 | ||
788 | drop: | 799 | drop: |
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 | ||
832 | static 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 | |||
821 | static int dn_rt_set_next_hop(struct dn_route *rt, struct dn_fib_res *res) | 837 | static 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 | ||