diff options
| -rw-r--r-- | include/net/neighbour.h | 3 | ||||
| -rw-r--r-- | net/core/neighbour.c | 34 |
2 files changed, 37 insertions, 0 deletions
diff --git a/include/net/neighbour.h b/include/net/neighbour.h index 14e3f017966b..afb8237b0a8c 100644 --- a/include/net/neighbour.h +++ b/include/net/neighbour.h | |||
| @@ -358,6 +358,7 @@ void neigh_for_each(struct neigh_table *tbl, | |||
| 358 | void (*cb)(struct neighbour *, void *), void *cookie); | 358 | void (*cb)(struct neighbour *, void *), void *cookie); |
| 359 | void __neigh_for_each_release(struct neigh_table *tbl, | 359 | void __neigh_for_each_release(struct neigh_table *tbl, |
| 360 | int (*cb)(struct neighbour *)); | 360 | int (*cb)(struct neighbour *)); |
| 361 | int neigh_xmit(int fam, struct net_device *, const void *, struct sk_buff *); | ||
| 361 | void pneigh_for_each(struct neigh_table *tbl, | 362 | void pneigh_for_each(struct neigh_table *tbl, |
| 362 | void (*cb)(struct pneigh_entry *)); | 363 | void (*cb)(struct pneigh_entry *)); |
| 363 | 364 | ||
| @@ -511,4 +512,6 @@ static inline void neigh_ha_snapshot(char *dst, const struct neighbour *n, | |||
| 511 | memcpy(dst, n->ha, dev->addr_len); | 512 | memcpy(dst, n->ha, dev->addr_len); |
| 512 | } while (read_seqretry(&n->ha_lock, seq)); | 513 | } while (read_seqretry(&n->ha_lock, seq)); |
| 513 | } | 514 | } |
| 515 | |||
| 516 | |||
| 514 | #endif | 517 | #endif |
diff --git a/net/core/neighbour.c b/net/core/neighbour.c index fe3c6eac5805..cffaf00561e7 100644 --- a/net/core/neighbour.c +++ b/net/core/neighbour.c | |||
| @@ -2391,6 +2391,40 @@ void __neigh_for_each_release(struct neigh_table *tbl, | |||
| 2391 | } | 2391 | } |
| 2392 | EXPORT_SYMBOL(__neigh_for_each_release); | 2392 | EXPORT_SYMBOL(__neigh_for_each_release); |
| 2393 | 2393 | ||
| 2394 | int neigh_xmit(int family, struct net_device *dev, | ||
| 2395 | const void *addr, struct sk_buff *skb) | ||
| 2396 | { | ||
| 2397 | int err; | ||
| 2398 | if (family == AF_PACKET) { | ||
| 2399 | err = dev_hard_header(skb, dev, ntohs(skb->protocol), | ||
| 2400 | addr, NULL, skb->len); | ||
| 2401 | if (err < 0) | ||
| 2402 | goto out_kfree_skb; | ||
| 2403 | err = dev_queue_xmit(skb); | ||
| 2404 | } else { | ||
| 2405 | struct neigh_table *tbl; | ||
| 2406 | struct neighbour *neigh; | ||
| 2407 | |||
| 2408 | err = -ENETDOWN; | ||
| 2409 | tbl = neigh_find_table(family); | ||
| 2410 | if (!tbl) | ||
| 2411 | goto out; | ||
| 2412 | neigh = __neigh_lookup_noref(tbl, addr, dev); | ||
| 2413 | if (!neigh) | ||
| 2414 | neigh = __neigh_create(tbl, addr, dev, false); | ||
| 2415 | err = PTR_ERR(neigh); | ||
| 2416 | if (IS_ERR(neigh)) | ||
| 2417 | goto out_kfree_skb; | ||
| 2418 | err = neigh->output(neigh, skb); | ||
| 2419 | } | ||
| 2420 | out: | ||
| 2421 | return err; | ||
| 2422 | out_kfree_skb: | ||
| 2423 | kfree_skb(skb); | ||
| 2424 | goto out; | ||
| 2425 | } | ||
| 2426 | EXPORT_SYMBOL(neigh_xmit); | ||
| 2427 | |||
| 2394 | #ifdef CONFIG_PROC_FS | 2428 | #ifdef CONFIG_PROC_FS |
| 2395 | 2429 | ||
| 2396 | static struct neighbour *neigh_get_first(struct seq_file *seq) | 2430 | static struct neighbour *neigh_get_first(struct seq_file *seq) |
