diff options
author | David Ahern <dsahern@gmail.com> | 2018-12-15 17:09:06 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2018-12-16 15:15:25 -0500 |
commit | df9b0e30d44c901ac27c0f38cd54511b3f130c6d (patch) | |
tree | a5c91efa13023045b3e5f5a14c7461fb84546219 | |
parent | 11fb60d1089f52dd9003d02cf2590c9b56eda840 (diff) |
neighbor: Add protocol attribute
Similar to routes and rules, add protocol attribute to neighbor entries
for easier tracking of how each was created.
Signed-off-by: David Ahern <dsahern@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | include/net/neighbour.h | 2 | ||||
-rw-r--r-- | include/uapi/linux/neighbour.h | 1 | ||||
-rw-r--r-- | net/core/neighbour.c | 24 |
3 files changed, 26 insertions, 1 deletions
diff --git a/include/net/neighbour.h b/include/net/neighbour.h index 30fd50adf234..66221f1991c0 100644 --- a/include/net/neighbour.h +++ b/include/net/neighbour.h | |||
@@ -149,6 +149,7 @@ struct neighbour { | |||
149 | __u8 nud_state; | 149 | __u8 nud_state; |
150 | __u8 type; | 150 | __u8 type; |
151 | __u8 dead; | 151 | __u8 dead; |
152 | u8 protocol; | ||
152 | seqlock_t ha_lock; | 153 | seqlock_t ha_lock; |
153 | unsigned char ha[ALIGN(MAX_ADDR_LEN, sizeof(unsigned long))] __aligned(8); | 154 | unsigned char ha[ALIGN(MAX_ADDR_LEN, sizeof(unsigned long))] __aligned(8); |
154 | struct hh_cache hh; | 155 | struct hh_cache hh; |
@@ -173,6 +174,7 @@ struct pneigh_entry { | |||
173 | possible_net_t net; | 174 | possible_net_t net; |
174 | struct net_device *dev; | 175 | struct net_device *dev; |
175 | u8 flags; | 176 | u8 flags; |
177 | u8 protocol; | ||
176 | u8 key[0]; | 178 | u8 key[0]; |
177 | }; | 179 | }; |
178 | 180 | ||
diff --git a/include/uapi/linux/neighbour.h b/include/uapi/linux/neighbour.h index 998155444e0d..cd144e3099a3 100644 --- a/include/uapi/linux/neighbour.h +++ b/include/uapi/linux/neighbour.h | |||
@@ -28,6 +28,7 @@ enum { | |||
28 | NDA_MASTER, | 28 | NDA_MASTER, |
29 | NDA_LINK_NETNSID, | 29 | NDA_LINK_NETNSID, |
30 | NDA_SRC_VNI, | 30 | NDA_SRC_VNI, |
31 | NDA_PROTOCOL, /* Originator of entry */ | ||
31 | __NDA_MAX | 32 | __NDA_MAX |
32 | }; | 33 | }; |
33 | 34 | ||
diff --git a/net/core/neighbour.c b/net/core/neighbour.c index 42b413774370..fb4372cb1de1 100644 --- a/net/core/neighbour.c +++ b/net/core/neighbour.c | |||
@@ -1828,6 +1828,7 @@ static int neigh_add(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
1828 | struct net_device *dev = NULL; | 1828 | struct net_device *dev = NULL; |
1829 | struct neighbour *neigh; | 1829 | struct neighbour *neigh; |
1830 | void *dst, *lladdr; | 1830 | void *dst, *lladdr; |
1831 | u8 protocol = 0; | ||
1831 | int err; | 1832 | int err; |
1832 | 1833 | ||
1833 | ASSERT_RTNL(); | 1834 | ASSERT_RTNL(); |
@@ -1867,6 +1868,14 @@ static int neigh_add(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
1867 | dst = nla_data(tb[NDA_DST]); | 1868 | dst = nla_data(tb[NDA_DST]); |
1868 | lladdr = tb[NDA_LLADDR] ? nla_data(tb[NDA_LLADDR]) : NULL; | 1869 | lladdr = tb[NDA_LLADDR] ? nla_data(tb[NDA_LLADDR]) : NULL; |
1869 | 1870 | ||
1871 | if (tb[NDA_PROTOCOL]) { | ||
1872 | if (nla_len(tb[NDA_PROTOCOL]) != sizeof(u8)) { | ||
1873 | NL_SET_ERR_MSG(extack, "Invalid protocol attribute"); | ||
1874 | goto out; | ||
1875 | } | ||
1876 | protocol = nla_get_u8(tb[NDA_PROTOCOL]); | ||
1877 | } | ||
1878 | |||
1870 | if (ndm->ndm_flags & NTF_PROXY) { | 1879 | if (ndm->ndm_flags & NTF_PROXY) { |
1871 | struct pneigh_entry *pn; | 1880 | struct pneigh_entry *pn; |
1872 | 1881 | ||
@@ -1874,6 +1883,8 @@ static int neigh_add(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
1874 | pn = pneigh_lookup(tbl, net, dst, dev, 1); | 1883 | pn = pneigh_lookup(tbl, net, dst, dev, 1); |
1875 | if (pn) { | 1884 | if (pn) { |
1876 | pn->flags = ndm->ndm_flags; | 1885 | pn->flags = ndm->ndm_flags; |
1886 | if (protocol) | ||
1887 | pn->protocol = protocol; | ||
1877 | err = 0; | 1888 | err = 0; |
1878 | } | 1889 | } |
1879 | goto out; | 1890 | goto out; |
@@ -1924,6 +1935,10 @@ static int neigh_add(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
1924 | } else | 1935 | } else |
1925 | err = __neigh_update(neigh, lladdr, ndm->ndm_state, flags, | 1936 | err = __neigh_update(neigh, lladdr, ndm->ndm_state, flags, |
1926 | NETLINK_CB(skb).portid, extack); | 1937 | NETLINK_CB(skb).portid, extack); |
1938 | |||
1939 | if (protocol) | ||
1940 | neigh->protocol = protocol; | ||
1941 | |||
1927 | neigh_release(neigh); | 1942 | neigh_release(neigh); |
1928 | 1943 | ||
1929 | out: | 1944 | out: |
@@ -2417,6 +2432,9 @@ static int neigh_fill_info(struct sk_buff *skb, struct neighbour *neigh, | |||
2417 | nla_put(skb, NDA_CACHEINFO, sizeof(ci), &ci)) | 2432 | nla_put(skb, NDA_CACHEINFO, sizeof(ci), &ci)) |
2418 | goto nla_put_failure; | 2433 | goto nla_put_failure; |
2419 | 2434 | ||
2435 | if (neigh->protocol && nla_put_u8(skb, NDA_PROTOCOL, neigh->protocol)) | ||
2436 | goto nla_put_failure; | ||
2437 | |||
2420 | nlmsg_end(skb, nlh); | 2438 | nlmsg_end(skb, nlh); |
2421 | return 0; | 2439 | return 0; |
2422 | 2440 | ||
@@ -2448,6 +2466,9 @@ static int pneigh_fill_info(struct sk_buff *skb, struct pneigh_entry *pn, | |||
2448 | if (nla_put(skb, NDA_DST, tbl->key_len, pn->key)) | 2466 | if (nla_put(skb, NDA_DST, tbl->key_len, pn->key)) |
2449 | goto nla_put_failure; | 2467 | goto nla_put_failure; |
2450 | 2468 | ||
2469 | if (pn->protocol && nla_put_u8(skb, NDA_PROTOCOL, pn->protocol)) | ||
2470 | goto nla_put_failure; | ||
2471 | |||
2451 | nlmsg_end(skb, nlh); | 2472 | nlmsg_end(skb, nlh); |
2452 | return 0; | 2473 | return 0; |
2453 | 2474 | ||
@@ -3103,7 +3124,8 @@ static inline size_t neigh_nlmsg_size(void) | |||
3103 | + nla_total_size(MAX_ADDR_LEN) /* NDA_DST */ | 3124 | + nla_total_size(MAX_ADDR_LEN) /* NDA_DST */ |
3104 | + nla_total_size(MAX_ADDR_LEN) /* NDA_LLADDR */ | 3125 | + nla_total_size(MAX_ADDR_LEN) /* NDA_LLADDR */ |
3105 | + nla_total_size(sizeof(struct nda_cacheinfo)) | 3126 | + nla_total_size(sizeof(struct nda_cacheinfo)) |
3106 | + nla_total_size(4); /* NDA_PROBES */ | 3127 | + nla_total_size(4) /* NDA_PROBES */ |
3128 | + nla_total_size(1); /* NDA_PROTOCOL */ | ||
3107 | } | 3129 | } |
3108 | 3130 | ||
3109 | static void __neigh_notify(struct neighbour *n, int type, int flags, | 3131 | static void __neigh_notify(struct neighbour *n, int type, int flags, |