aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/dn_route.h2
-rw-r--r--net/decnet/dn_neigh.c2
-rw-r--r--net/decnet/dn_route.c36
3 files changed, 32 insertions, 8 deletions
diff --git a/include/net/dn_route.h b/include/net/dn_route.h
index c507e05d172f..4f7d6a182381 100644
--- a/include/net/dn_route.h
+++ b/include/net/dn_route.h
@@ -67,6 +67,8 @@ extern void dn_rt_cache_flush(int delay);
67struct dn_route { 67struct dn_route {
68 struct dst_entry dst; 68 struct dst_entry dst;
69 69
70 struct neighbour *n;
71
70 struct flowidn fld; 72 struct flowidn fld;
71 73
72 __le16 rt_saddr; 74 __le16 rt_saddr;
diff --git a/net/decnet/dn_neigh.c b/net/decnet/dn_neigh.c
index 8e9a35b17df4..3aede1b459fd 100644
--- a/net/decnet/dn_neigh.c
+++ b/net/decnet/dn_neigh.c
@@ -202,7 +202,7 @@ static int dn_neigh_output_packet(struct sk_buff *skb)
202{ 202{
203 struct dst_entry *dst = skb_dst(skb); 203 struct dst_entry *dst = skb_dst(skb);
204 struct dn_route *rt = (struct dn_route *)dst; 204 struct dn_route *rt = (struct dn_route *)dst;
205 struct neighbour *neigh = dst_get_neighbour_noref(dst); 205 struct neighbour *neigh = rt->n;
206 struct net_device *dev = neigh->dev; 206 struct net_device *dev = neigh->dev;
207 char mac_addr[ETH_ALEN]; 207 char mac_addr[ETH_ALEN];
208 unsigned int seq; 208 unsigned int seq;
diff --git a/net/decnet/dn_route.c b/net/decnet/dn_route.c
index 60e4c6e1bac0..6e74b3f110bc 100644
--- a/net/decnet/dn_route.c
+++ b/net/decnet/dn_route.c
@@ -114,6 +114,7 @@ static struct dst_entry *dn_dst_check(struct dst_entry *, __u32);
114static unsigned int dn_dst_default_advmss(const struct dst_entry *dst); 114static unsigned int dn_dst_default_advmss(const struct dst_entry *dst);
115static unsigned int dn_dst_mtu(const struct dst_entry *dst); 115static unsigned int dn_dst_mtu(const struct dst_entry *dst);
116static void dn_dst_destroy(struct dst_entry *); 116static void dn_dst_destroy(struct dst_entry *);
117static void dn_dst_ifdown(struct dst_entry *, struct net_device *dev, int how);
117static struct dst_entry *dn_dst_negative_advice(struct dst_entry *); 118static struct dst_entry *dn_dst_negative_advice(struct dst_entry *);
118static void dn_dst_link_failure(struct sk_buff *); 119static void dn_dst_link_failure(struct sk_buff *);
119static void dn_dst_update_pmtu(struct dst_entry *dst, u32 mtu); 120static void dn_dst_update_pmtu(struct dst_entry *dst, u32 mtu);
@@ -140,6 +141,7 @@ static struct dst_ops dn_dst_ops = {
140 .mtu = dn_dst_mtu, 141 .mtu = dn_dst_mtu,
141 .cow_metrics = dst_cow_metrics_generic, 142 .cow_metrics = dst_cow_metrics_generic,
142 .destroy = dn_dst_destroy, 143 .destroy = dn_dst_destroy,
144 .ifdown = dn_dst_ifdown,
143 .negative_advice = dn_dst_negative_advice, 145 .negative_advice = dn_dst_negative_advice,
144 .link_failure = dn_dst_link_failure, 146 .link_failure = dn_dst_link_failure,
145 .update_pmtu = dn_dst_update_pmtu, 147 .update_pmtu = dn_dst_update_pmtu,
@@ -148,9 +150,27 @@ static struct dst_ops dn_dst_ops = {
148 150
149static void dn_dst_destroy(struct dst_entry *dst) 151static void dn_dst_destroy(struct dst_entry *dst)
150{ 152{
153 struct dn_route *rt = (struct dn_route *) dst;
154
155 if (rt->n)
156 neigh_release(rt->n);
151 dst_destroy_metrics_generic(dst); 157 dst_destroy_metrics_generic(dst);
152} 158}
153 159
160static void dn_dst_ifdown(struct dst_entry *dst, struct net_device *dev, int how)
161{
162 if (how) {
163 struct dn_route *rt = (struct dn_route *) dst;
164 struct neighbour *n = rt->n;
165
166 if (n && n->dev == dev) {
167 n->dev = dev_net(dev)->loopback_dev;
168 dev_hold(n->dev);
169 dev_put(dev);
170 }
171 }
172}
173
154static __inline__ unsigned int dn_hash(__le16 src, __le16 dst) 174static __inline__ unsigned int dn_hash(__le16 src, __le16 dst)
155{ 175{
156 __u16 tmp = (__u16 __force)(src ^ dst); 176 __u16 tmp = (__u16 __force)(src ^ dst);
@@ -246,7 +266,8 @@ static int dn_dst_gc(struct dst_ops *ops)
246 */ 266 */
247static void dn_dst_update_pmtu(struct dst_entry *dst, u32 mtu) 267static void dn_dst_update_pmtu(struct dst_entry *dst, u32 mtu)
248{ 268{
249 struct neighbour *n = dst_get_neighbour_noref(dst); 269 struct dn_route *rt = (struct dn_route *) dst;
270 struct neighbour *n = rt->n;
250 u32 min_mtu = 230; 271 u32 min_mtu = 230;
251 struct dn_dev *dn; 272 struct dn_dev *dn;
252 273
@@ -715,7 +736,8 @@ out:
715static int dn_to_neigh_output(struct sk_buff *skb) 736static int dn_to_neigh_output(struct sk_buff *skb)
716{ 737{
717 struct dst_entry *dst = skb_dst(skb); 738 struct dst_entry *dst = skb_dst(skb);
718 struct neighbour *n = dst_get_neighbour_noref(dst); 739 struct dn_route *rt = (struct dn_route *) dst;
740 struct neighbour *n = rt->n;
719 741
720 return n->output(n, skb); 742 return n->output(n, skb);
721} 743}
@@ -729,7 +751,7 @@ static int dn_output(struct sk_buff *skb)
729 751
730 int err = -EINVAL; 752 int err = -EINVAL;
731 753
732 if (dst_get_neighbour_noref(dst) == NULL) 754 if (rt->n == NULL)
733 goto error; 755 goto error;
734 756
735 skb->dev = dev; 757 skb->dev = dev;
@@ -852,11 +874,11 @@ static int dn_rt_set_next_hop(struct dn_route *rt, struct dn_fib_res *res)
852 } 874 }
853 rt->rt_type = res->type; 875 rt->rt_type = res->type;
854 876
855 if (dev != NULL && dst_get_neighbour_noref(&rt->dst) == NULL) { 877 if (dev != NULL && rt->n == NULL) {
856 n = __neigh_lookup_errno(&dn_neigh_table, &rt->rt_gateway, dev); 878 n = __neigh_lookup_errno(&dn_neigh_table, &rt->rt_gateway, dev);
857 if (IS_ERR(n)) 879 if (IS_ERR(n))
858 return PTR_ERR(n); 880 return PTR_ERR(n);
859 dst_set_neighbour(&rt->dst, n); 881 rt->n = n;
860 } 882 }
861 883
862 if (dst_metric(&rt->dst, RTAX_MTU) > rt->dst.dev->mtu) 884 if (dst_metric(&rt->dst, RTAX_MTU) > rt->dst.dev->mtu)
@@ -1163,7 +1185,7 @@ make_route:
1163 rt->rt_dst_map = fld.daddr; 1185 rt->rt_dst_map = fld.daddr;
1164 rt->rt_src_map = fld.saddr; 1186 rt->rt_src_map = fld.saddr;
1165 1187
1166 dst_set_neighbour(&rt->dst, neigh); 1188 rt->n = neigh;
1167 neigh = NULL; 1189 neigh = NULL;
1168 1190
1169 rt->dst.lastuse = jiffies; 1191 rt->dst.lastuse = jiffies;
@@ -1433,7 +1455,7 @@ make_route:
1433 rt->fld.flowidn_iif = in_dev->ifindex; 1455 rt->fld.flowidn_iif = in_dev->ifindex;
1434 rt->fld.flowidn_mark = fld.flowidn_mark; 1456 rt->fld.flowidn_mark = fld.flowidn_mark;
1435 1457
1436 dst_set_neighbour(&rt->dst, neigh); 1458 rt->n = neigh;
1437 rt->dst.lastuse = jiffies; 1459 rt->dst.lastuse = jiffies;
1438 rt->dst.output = dn_rt_bug; 1460 rt->dst.output = dn_rt_bug;
1439 switch (res.type) { 1461 switch (res.type) {