neighbour tables via rtnetlink v2
Subsystems (3)
PATCH 1/1 neighbour tables via rtnetlink v2
Setting of values is still untested due to missing userspace part but reading of the configuration and the statistics works. Example libnl output including full statistics:
arp_cache entries 2 reachable 26s 156msec retrans 1s
thresh1 128 thresh2 512 thresh3 1024
key-len 4 entry-size 152 last-flush 24m 19s 474msec hash-rand 0xC7089C95/0x00000003 gc 1 last-rand 4s 472msec refcnt 1 qlen 3 proxy-qlen 64 locktime 1s base-reachable 30s app-probes 0 ucast-probes 3 mcast-probes 3 gc-stale-time 1m probe-delay 5s anycast-delay 1s proxy-delay 800msec lookups 65 hits 62 failed 0 allocations 3 destroys 1 hash-grows 1 forced-gc-runs 0 periodic-gc-runs 387 rcv-unicast-probes 0 rcv-multicast-probes 0
and for device specific parameter sets:
arp_cache<eth0> reachable 22s 443msec retrans 1s
refcnt 3 qlen 3 proxy-qlen 64 locktime 1s base-reachable 30s app-probes 0 ucast-probes 3 mcast-probes 3 gc-stale-time 1m probe-delay 5s anycast-delay 1s proxy-delay 800msec
I use msecs for all time values instead of user HZ and seconds to allow for greater precision and less headache for userspace.
Attached are 3 patches, new netlink and rtnetlink shortcuts for prettier message building and the actual new code.
[NETLINK] New message building macros
NLMSG_NEW(skb, pid, sequence, type, length)
Start a new netlink message, returns message header.
NLMSG_NEW_ANSWER(skb, nlcb, type, length)
Start a new netlink message as answer to a request, returns message header.
NLMSG_END(skb, nlh)
End a netlink message, fixes total message length, returns skb->len.
NLMSG_CANCEL(skb, nlh)
Cancel the building process and trim whole message from skb again, returns -1.
---
commit 7250be2b3e192904e66ce314a3d2d2e46bc8bce2
tree 4f7a765c06386f20a3a9b68eea4efd57e2b354ad
parent d1faeaeb95a05275cf0c5b51b88f2fa833434625
author Thomas Graf <[email protected]> Tue, 24 May 2005 14:26:10 +0200 committer Thomas Graf <[email protected]> Tue, 24 May 2005 14:26:10 +0200
include/linux/netlink.h | 22 ++++++++++++++++++++-- 1 files changed, 20 insertions(+), 2 deletions(-)
include/linux/netlink.h (mode:100644) +20 -2
@@ -170,9 +170,27 @@ return nlh; } +#define NLMSG_END(skb, nlh) \ +({ (nlh)->nlmsg_len = (skb)->tail - (unsigned char *) (nlh); \ + skb->len; }) + +#define NLMSG_CANCEL(skb, nlh) \ +({ skb_trim((skb), (unsigned char *) (nlh) - (skb)->data); \ + -1; }) + #define NLMSG_PUT(skb, pid, seq, type, len) \ -({ if (skb_tailroom(skb) < (int)NLMSG_SPACE(len)) goto nlmsg_failure; \ - __nlmsg_put(skb, pid, seq, type, len); }) +({ if (skb_tailroom(skb) < (int)NLMSG_SPACE(len)) \ + goto nlmsg_failure; \ + __nlmsg_put(skb, pid, seq, type, len); }) + +#define NLMSG_NEW(skb, pid, seq, type, len) \ +({ struct nlmsghdr *_hdr = NLMSG_PUT(skb, pid, seq, type, len); \ + _hdr->nlmsg_flags = pid ? NLM_F_MULTI : 0; \ + _hdr; }) + +#define NLMSG_NEW_ANSWER(skb, cb, type, len) \ + NLMSG_NEW(skb, NETLINK_CB((cb)->skb).pid, \ + (cb)->nlh->nlmsg_seq, type, len) extern int netlink_dump_start(struct sock *ssk, struct sk_buff *skb, struct nlmsghdr *nlh,
[RTNETLINK] Routing attribute related shortcuts
RTA_GET_U(32|64)(tlv)
Assumes tlv is a u32/u64 field and returns its value.
RTA_GET_[M]SECS(tlv)
Assumes tlv is a u64 and transports jiffies converted to seconds or milliseconds and returns its value.
RTA_PUT_U(32|64)(skb, type, value)
Appends %value as fixed u32/u64 to %skb as TLV %type.
RTA_PUT_[M]SECS(skb, type, jiffies)
Converts %jiffies to secs/msecs and appends it as u64 to %skb as TLV %type.
RTA_PUT_STRING(skb, type, string)
Appends %NUL terminated %string to %skb as TLV %type.
RTA_NEST(skb, type)
Starts a nested TLV %type and returns the nesting handle.
RTA_END_NEST(skb, nesting_handle)
Finishes the nested TLV %nesting_handle, must be called symmetric to RTA_NEST().
---
commit edab564809178ad08753d8d620fc9b518898fd79
tree d3a4a96913f779af77cd3486cdeb701dc92efed0
parent 7250be2b3e192904e66ce314a3d2d2e46bc8bce2
author Thomas Graf <[email protected]> Tue, 24 May 2005 18:47:38 +0200 committer Thomas Graf <[email protected]> Tue, 24 May 2005 18:47:38 +0200
include/linux/rtnetlink.h | 37 +++++++++++++++++++++++++++++++++++++ 1 files changed, 37 insertions(+)
include/linux/rtnetlink.h (mode:100644) +37 -0
@@ -123,8 +123,20 @@ #define RTA_DATA(rta) ((void*)(((char*)(rta)) + RTA_LENGTH(0))) #define RTA_PAYLOAD(rta) ((int)((rta)->rta_len) - RTA_LENGTH(0)) +#define RTA_GET_U32(rta) \ +({ if (!rta || RTA_PAYLOAD(rta) < sizeof(u32)) \ + goto rtattr_failure; \ + *(u32 *) RTA_DATA(rta); }) +#define RTA_GET_U64(rta) \ +({ u64 _tmp; \ + if (!rta || RTA_PAYLOAD(rta) < sizeof(u64)) \ + goto rtattr_failure; \ + memcpy(&_tmp, RTA_DATA(rta), sizeof(_tmp)); \ + _tmp; }) +#define RTA_GET_SECS(rta) ((unsigned long) RTA_GET_U64(rta) * HZ) +#define RTA_GET_MSECS(rta) (msecs_to_jiffies((unsigned long) RTA_GET_U64(rta))) /****************************************************************************** * Definitions used in routing table administration.
@@ -789,6 +801,31 @@ ({ if (unlikely(skb_tailroom(skb) < (int)(attrlen))) \ goto rtattr_failure; \ memcpy(skb_put(skb, RTA_ALIGN(attrlen)), data, attrlen); }) + +#define RTA_PUT_U32(skb, attrtype, value) \ +({ u32 _tmp = (value); \ + RTA_PUT(skb, attrtype, sizeof(u32), &_tmp); }) + +#define RTA_PUT_U64(skb, attrtype, value) \ +({ u64 _tmp = (value); \ + RTA_PUT(skb, attrtype, sizeof(u64), &_tmp); }) + +#define RTA_PUT_SECS(skb, attrtype, value) \ + RTA_PUT_U64(skb, attrtype, (value) / HZ) + +#define RTA_PUT_MSECS(skb, attrtype, value) \ + RTA_PUT_U64(skb, attrtype, jiffies_to_msecs(value)) + +#define RTA_PUT_STRING(skb, attrtype, value) \ + RTA_PUT(skb, attrtype, strlen(value) + 1, value) + +#define RTA_NEST(skb, type) \ +({ struct rtattr *__start = (struct rtattr *) (skb)->tail; \ + RTA_PUT(skb, type, 0, NULL); \ + __start; }) + +#define RTA_END_NEST(skb, start) \ +({ (start)->rta_len = ((skb)->tail - (unsigned char *) (start)); }) static inline struct rtattr * __rta_reserve(struct sk_buff *skb, int attrtype, int attrlen)
[NEIGH] neighbour table configuration and statistics via rtnetlink
---
commit 51565b40aef15f4e4b5748f9d71121e029bc4fe7
tree 7fdf80f0bf19d8ed075ee7f423173f0838c87683
parent edab564809178ad08753d8d620fc9b518898fd79
author Thomas Graf <[email protected]> Tue, 24 May 2005 18:48:08 +0200 committer Thomas Graf <[email protected]> Tue, 24 May 2005 18:48:08 +0200
include/linux/rtnetlink.h | 94 +++++++++++++ include/net/neighbour.h | 4 net/core/neighbour.c | 310 +++++++++++++++++++++++++++++++++++++++++++- net/core/rtnetlink.c | 20 +- security/selinux/nlmsgtab.c | 2 5 files changed, 419 insertions(+), 11 deletions(-)
include/linux/rtnetlink.h (mode:100644) +94 -0
106 lines not on this page · raw message
include/net/neighbour.h (mode:100644) +4 -0
@@ -65,6 +65,7 @@ struct neigh_parms { + struct net_device *dev; struct neigh_parms *next; int (*neigh_setup)(struct neighbour *); struct neigh_table *tbl;
@@ -252,6 +253,9 @@ extern int neigh_delete(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg); extern void neigh_app_ns(struct neighbour *n); +extern int neightbl_dump_info(struct sk_buff *skb, struct netlink_callback *cb); +extern int neightbl_set(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg); + extern void neigh_for_each(struct neigh_table *tbl, void (*cb)(struct neighbour *, void *), void *cookie); extern void __neigh_for_each_release(struct neigh_table *tbl, int (*cb)(struct neighbour *)); extern void pneigh_for_each(struct neigh_table *tbl, void (*cb)(struct pneigh_entry *));
net/core/neighbour.c (mode:100644) +307 -3
334 lines not on this page · raw message
net/core/rtnetlink.c (mode:100644) +12 -8
@@ -100,6 +100,7 @@ [RTM_FAM(RTM_NEWPREFIX)] = NLMSG_LENGTH(sizeof(struct rtgenmsg)), [RTM_FAM(RTM_GETMULTICAST)] = NLMSG_LENGTH(sizeof(struct rtgenmsg)), [RTM_FAM(RTM_GETANYCAST)] = NLMSG_LENGTH(sizeof(struct rtgenmsg)), + [RTM_FAM(RTM_NEWNEIGHTBL)] = NLMSG_LENGTH(sizeof(struct ndtmsg)), }; static const int rta_max[RTM_NR_FAMILIES] =
@@ -113,6 +114,7 @@ [RTM_FAM(RTM_NEWTCLASS)] = TCA_MAX, [RTM_FAM(RTM_NEWTFILTER)] = TCA_MAX, [RTM_FAM(RTM_NEWACTION)] = TCAA_MAX, + [RTM_FAM(RTM_NEWNEIGHTBL)] = NDTA_MAX, }; void __rta_fill(struct sk_buff *skb, int attrtype, int attrlen, const void *data)
@@ -649,14 +651,16 @@ static struct rtnetlink_link link_rtnetlink_table[RTM_NR_MSGTYPES] = { - [RTM_GETLINK - RTM_BASE] = { .dumpit = rtnetlink_dump_ifinfo }, - [RTM_SETLINK - RTM_BASE] = { .doit = do_setlink }, - [RTM_GETADDR - RTM_BASE] = { .dumpit = rtnetlink_dump_all }, - [RTM_GETROUTE - RTM_BASE] = { .dumpit = rtnetlink_dump_all }, - [RTM_NEWNEIGH - RTM_BASE] = { .doit = neigh_add }, - [RTM_DELNEIGH - RTM_BASE] = { .doit = neigh_delete }, - [RTM_GETNEIGH - RTM_BASE] = { .dumpit = neigh_dump_info }, - [RTM_GETRULE - RTM_BASE] = { .dumpit = rtnetlink_dump_all }, + [RTM_GETLINK - RTM_BASE] = { .dumpit = rtnetlink_dump_ifinfo }, + [RTM_SETLINK - RTM_BASE] = { .doit = do_setlink }, + [RTM_GETADDR - RTM_BASE] = { .dumpit = rtnetlink_dump_all }, + [RTM_GETROUTE - RTM_BASE] = { .dumpit = rtnetlink_dump_all }, + [RTM_NEWNEIGH - RTM_BASE] = { .doit = neigh_add }, + [RTM_DELNEIGH - RTM_BASE] = { .doit = neigh_delete }, + [RTM_GETNEIGH - RTM_BASE] = { .dumpit = neigh_dump_info }, + [RTM_GETRULE - RTM_BASE] = { .dumpit = rtnetlink_dump_all }, + [RTM_GETNEIGHTBL - RTM_BASE] = { .dumpit = neightbl_dump_info }, + [RTM_SETNEIGHTBL - RTM_BASE] = { .doit = neightbl_set }, }; static int rtnetlink_event(struct notifier_block *this, unsigned long event, void *ptr)
security/selinux/nlmsgtab.c (mode:100644) +2 -0
@@ -63,6 +63,8 @@ { RTM_GETPREFIX, NETLINK_ROUTE_SOCKET__NLMSG_READ }, { RTM_GETMULTICAST, NETLINK_ROUTE_SOCKET__NLMSG_READ }, { RTM_GETANYCAST, NETLINK_ROUTE_SOCKET__NLMSG_READ }, + { RTM_GETNEIGHTBL, NETLINK_ROUTE_SOCKET__NLMSG_READ }, + { RTM_SETNEIGHTBL, NETLINK_ROUTE_SOCKET__NLMSG_WRITE }, }; static struct nlmsg_perm nlmsg_firewall_perms[] =