diff options
-rw-r--r-- | include/net/dn_neigh.h | 1 | ||||
-rw-r--r-- | net/decnet/dn_neigh.c | 105 | ||||
-rw-r--r-- | net/decnet/dn_route.c | 9 |
3 files changed, 55 insertions, 60 deletions
diff --git a/include/net/dn_neigh.h b/include/net/dn_neigh.h index fac4e3f4a6d3..0f26aa707e62 100644 --- a/include/net/dn_neigh.h +++ b/include/net/dn_neigh.h | |||
@@ -22,6 +22,7 @@ int dn_neigh_router_hello(struct sk_buff *skb); | |||
22 | int dn_neigh_endnode_hello(struct sk_buff *skb); | 22 | int dn_neigh_endnode_hello(struct sk_buff *skb); |
23 | void dn_neigh_pointopoint_hello(struct sk_buff *skb); | 23 | void dn_neigh_pointopoint_hello(struct sk_buff *skb); |
24 | int dn_neigh_elist(struct net_device *dev, unsigned char *ptr, int n); | 24 | int dn_neigh_elist(struct net_device *dev, unsigned char *ptr, int n); |
25 | int dn_to_neigh_output(struct sk_buff *skb); | ||
25 | 26 | ||
26 | extern struct neigh_table dn_neigh_table; | 27 | extern struct neigh_table dn_neigh_table; |
27 | 28 | ||
diff --git a/net/decnet/dn_neigh.c b/net/decnet/dn_neigh.c index ee7d1cef0027..be1f08cdad29 100644 --- a/net/decnet/dn_neigh.c +++ b/net/decnet/dn_neigh.c | |||
@@ -49,41 +49,17 @@ | |||
49 | #include <net/dn_route.h> | 49 | #include <net/dn_route.h> |
50 | 50 | ||
51 | static int dn_neigh_construct(struct neighbour *); | 51 | static int dn_neigh_construct(struct neighbour *); |
52 | static void dn_long_error_report(struct neighbour *, struct sk_buff *); | 52 | static void dn_neigh_error_report(struct neighbour *, struct sk_buff *); |
53 | static void dn_short_error_report(struct neighbour *, struct sk_buff *); | 53 | static int dn_neigh_output(struct neighbour *neigh, struct sk_buff *skb); |
54 | static int dn_long_output(struct neighbour *, struct sk_buff *); | ||
55 | static int dn_short_output(struct neighbour *, struct sk_buff *); | ||
56 | static int dn_phase3_output(struct neighbour *, struct sk_buff *); | ||
57 | |||
58 | |||
59 | /* | ||
60 | * For talking to broadcast devices: Ethernet & PPP | ||
61 | */ | ||
62 | static const struct neigh_ops dn_long_ops = { | ||
63 | .family = AF_DECnet, | ||
64 | .error_report = dn_long_error_report, | ||
65 | .output = dn_long_output, | ||
66 | .connected_output = dn_long_output, | ||
67 | }; | ||
68 | 54 | ||
69 | /* | 55 | /* |
70 | * For talking to pointopoint and multidrop devices: DDCMP and X.25 | 56 | * Operations for adding the link layer header. |
71 | */ | 57 | */ |
72 | static const struct neigh_ops dn_short_ops = { | 58 | static const struct neigh_ops dn_neigh_ops = { |
73 | .family = AF_DECnet, | 59 | .family = AF_DECnet, |
74 | .error_report = dn_short_error_report, | 60 | .error_report = dn_neigh_error_report, |
75 | .output = dn_short_output, | 61 | .output = dn_neigh_output, |
76 | .connected_output = dn_short_output, | 62 | .connected_output = dn_neigh_output, |
77 | }; | ||
78 | |||
79 | /* | ||
80 | * For talking to DECnet phase III nodes | ||
81 | */ | ||
82 | static const struct neigh_ops dn_phase3_ops = { | ||
83 | .family = AF_DECnet, | ||
84 | .error_report = dn_short_error_report, /* Can use short version here */ | ||
85 | .output = dn_phase3_output, | ||
86 | .connected_output = dn_phase3_output, | ||
87 | }; | 63 | }; |
88 | 64 | ||
89 | static u32 dn_neigh_hash(const void *pkey, | 65 | static u32 dn_neigh_hash(const void *pkey, |
@@ -153,16 +129,9 @@ static int dn_neigh_construct(struct neighbour *neigh) | |||
153 | 129 | ||
154 | __neigh_parms_put(neigh->parms); | 130 | __neigh_parms_put(neigh->parms); |
155 | neigh->parms = neigh_parms_clone(parms); | 131 | neigh->parms = neigh_parms_clone(parms); |
156 | |||
157 | if (dn_db->use_long) | ||
158 | neigh->ops = &dn_long_ops; | ||
159 | else | ||
160 | neigh->ops = &dn_short_ops; | ||
161 | rcu_read_unlock(); | 132 | rcu_read_unlock(); |
162 | 133 | ||
163 | if (dn->flags & DN_NDFLAG_P3) | 134 | neigh->ops = &dn_neigh_ops; |
164 | neigh->ops = &dn_phase3_ops; | ||
165 | |||
166 | neigh->nud_state = NUD_NOARP; | 135 | neigh->nud_state = NUD_NOARP; |
167 | neigh->output = neigh->ops->connected_output; | 136 | neigh->output = neigh->ops->connected_output; |
168 | 137 | ||
@@ -194,24 +163,16 @@ static int dn_neigh_construct(struct neighbour *neigh) | |||
194 | return 0; | 163 | return 0; |
195 | } | 164 | } |
196 | 165 | ||
197 | static void dn_long_error_report(struct neighbour *neigh, struct sk_buff *skb) | 166 | static void dn_neigh_error_report(struct neighbour *neigh, struct sk_buff *skb) |
198 | { | ||
199 | printk(KERN_DEBUG "dn_long_error_report: called\n"); | ||
200 | kfree_skb(skb); | ||
201 | } | ||
202 | |||
203 | |||
204 | static void dn_short_error_report(struct neighbour *neigh, struct sk_buff *skb) | ||
205 | { | 167 | { |
206 | printk(KERN_DEBUG "dn_short_error_report: called\n"); | 168 | printk(KERN_DEBUG "dn_neigh_error_report: called\n"); |
207 | kfree_skb(skb); | 169 | kfree_skb(skb); |
208 | } | 170 | } |
209 | 171 | ||
210 | static int dn_neigh_output_packet(struct sk_buff *skb) | 172 | static int dn_neigh_output(struct neighbour *neigh, struct sk_buff *skb) |
211 | { | 173 | { |
212 | struct dst_entry *dst = skb_dst(skb); | 174 | struct dst_entry *dst = skb_dst(skb); |
213 | struct dn_route *rt = (struct dn_route *)dst; | 175 | struct dn_route *rt = (struct dn_route *)dst; |
214 | struct neighbour *neigh = rt->n; | ||
215 | struct net_device *dev = neigh->dev; | 176 | struct net_device *dev = neigh->dev; |
216 | char mac_addr[ETH_ALEN]; | 177 | char mac_addr[ETH_ALEN]; |
217 | unsigned int seq; | 178 | unsigned int seq; |
@@ -233,6 +194,18 @@ static int dn_neigh_output_packet(struct sk_buff *skb) | |||
233 | return err; | 194 | return err; |
234 | } | 195 | } |
235 | 196 | ||
197 | static int dn_neigh_output_packet(struct sk_buff *skb) | ||
198 | { | ||
199 | struct dst_entry *dst = skb_dst(skb); | ||
200 | struct dn_route *rt = (struct dn_route *)dst; | ||
201 | struct neighbour *neigh = rt->n; | ||
202 | |||
203 | return neigh->output(neigh, skb); | ||
204 | } | ||
205 | |||
206 | /* | ||
207 | * For talking to broadcast devices: Ethernet & PPP | ||
208 | */ | ||
236 | static int dn_long_output(struct neighbour *neigh, struct sk_buff *skb) | 209 | static int dn_long_output(struct neighbour *neigh, struct sk_buff *skb) |
237 | { | 210 | { |
238 | struct net_device *dev = neigh->dev; | 211 | struct net_device *dev = neigh->dev; |
@@ -276,6 +249,9 @@ static int dn_long_output(struct neighbour *neigh, struct sk_buff *skb) | |||
276 | neigh->dev, dn_neigh_output_packet); | 249 | neigh->dev, dn_neigh_output_packet); |
277 | } | 250 | } |
278 | 251 | ||
252 | /* | ||
253 | * For talking to pointopoint and multidrop devices: DDCMP and X.25 | ||
254 | */ | ||
279 | static int dn_short_output(struct neighbour *neigh, struct sk_buff *skb) | 255 | static int dn_short_output(struct neighbour *neigh, struct sk_buff *skb) |
280 | { | 256 | { |
281 | struct net_device *dev = neigh->dev; | 257 | struct net_device *dev = neigh->dev; |
@@ -313,7 +289,8 @@ static int dn_short_output(struct neighbour *neigh, struct sk_buff *skb) | |||
313 | } | 289 | } |
314 | 290 | ||
315 | /* | 291 | /* |
316 | * Phase 3 output is the same is short output, execpt that | 292 | * For talking to DECnet phase III nodes |
293 | * Phase 3 output is the same as short output, execpt that | ||
317 | * it clears the area bits before transmission. | 294 | * it clears the area bits before transmission. |
318 | */ | 295 | */ |
319 | static int dn_phase3_output(struct neighbour *neigh, struct sk_buff *skb) | 296 | static int dn_phase3_output(struct neighbour *neigh, struct sk_buff *skb) |
@@ -351,6 +328,32 @@ static int dn_phase3_output(struct neighbour *neigh, struct sk_buff *skb) | |||
351 | neigh->dev, dn_neigh_output_packet); | 328 | neigh->dev, dn_neigh_output_packet); |
352 | } | 329 | } |
353 | 330 | ||
331 | int dn_to_neigh_output(struct sk_buff *skb) | ||
332 | { | ||
333 | struct dst_entry *dst = skb_dst(skb); | ||
334 | struct dn_route *rt = (struct dn_route *) dst; | ||
335 | struct neighbour *neigh = rt->n; | ||
336 | struct dn_neigh *dn = (struct dn_neigh *)neigh; | ||
337 | struct dn_dev *dn_db; | ||
338 | bool use_long; | ||
339 | |||
340 | rcu_read_lock(); | ||
341 | dn_db = rcu_dereference(neigh->dev->dn_ptr); | ||
342 | if (dn_db == NULL) { | ||
343 | rcu_read_unlock(); | ||
344 | return -EINVAL; | ||
345 | } | ||
346 | use_long = dn_db->use_long; | ||
347 | rcu_read_unlock(); | ||
348 | |||
349 | if (dn->flags & DN_NDFLAG_P3) | ||
350 | return dn_phase3_output(neigh, skb); | ||
351 | if (use_long) | ||
352 | return dn_long_output(neigh, skb); | ||
353 | else | ||
354 | return dn_short_output(neigh, skb); | ||
355 | } | ||
356 | |||
354 | /* | 357 | /* |
355 | * Unfortunately, the neighbour code uses the device in its hash | 358 | * Unfortunately, the neighbour code uses the device in its hash |
356 | * function, so we don't get any advantage from it. This function | 359 | * function, so we don't get any advantage from it. This function |
diff --git a/net/decnet/dn_route.c b/net/decnet/dn_route.c index 3b81092771f8..771815575dbd 100644 --- a/net/decnet/dn_route.c +++ b/net/decnet/dn_route.c | |||
@@ -743,15 +743,6 @@ out: | |||
743 | return NET_RX_DROP; | 743 | return NET_RX_DROP; |
744 | } | 744 | } |
745 | 745 | ||
746 | static int dn_to_neigh_output(struct sk_buff *skb) | ||
747 | { | ||
748 | struct dst_entry *dst = skb_dst(skb); | ||
749 | struct dn_route *rt = (struct dn_route *) dst; | ||
750 | struct neighbour *n = rt->n; | ||
751 | |||
752 | return n->output(n, skb); | ||
753 | } | ||
754 | |||
755 | static int dn_output(struct sock *sk, struct sk_buff *skb) | 746 | static int dn_output(struct sock *sk, struct sk_buff *skb) |
756 | { | 747 | { |
757 | struct dst_entry *dst = skb_dst(skb); | 748 | struct dst_entry *dst = skb_dst(skb); |