diff options
author | Thomas Graf <tgraf@infradead.org> | 2010-11-15 23:30:14 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-11-17 14:28:24 -0500 |
commit | f8ff182c716c6f11ca3061961f5722f26a14e101 (patch) | |
tree | 6ea721a7feb71850c61b9d02400d162674d91c21 /include | |
parent | d67ef35fff67845c64d806c033cc7c569ccebfff (diff) |
rtnetlink: Link address family API
Each net_device contains address family specific data such as
per device settings and statistics. We already expose this data
via procfs/sysfs and partially netlink.
The netlink method requires the requester to send one RTM_GETLINK
request for each address family it wishes to receive data of
and then merge this data itself.
This patch implements a new API which combines all address family
specific link data in a new netlink attribute IFLA_AF_SPEC.
IFLA_AF_SPEC contains a sequence of nested attributes, one for each
address family which in turn defines the structure of its own
attribute. Example:
[IFLA_AF_SPEC] = {
[AF_INET] = {
[IFLA_INET_CONF] = ...,
},
[AF_INET6] = {
[IFLA_INET6_FLAGS] = ...,
[IFLA_INET6_CONF] = ...,
}
}
The API also allows for address families to implement a function
which parses the IFLA_AF_SPEC attribute sent by userspace to
implement address family specific link options.
Signed-off-by: Thomas Graf <tgraf@infradead.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'include')
-rw-r--r-- | include/linux/if_link.h | 19 | ||||
-rw-r--r-- | include/net/rtnetlink.h | 31 |
2 files changed, 50 insertions, 0 deletions
diff --git a/include/linux/if_link.h b/include/linux/if_link.h index 2fc66dd783ee..443d04a66a79 100644 --- a/include/linux/if_link.h +++ b/include/linux/if_link.h | |||
@@ -80,6 +80,24 @@ struct rtnl_link_ifmap { | |||
80 | __u8 port; | 80 | __u8 port; |
81 | }; | 81 | }; |
82 | 82 | ||
83 | /* | ||
84 | * IFLA_AF_SPEC | ||
85 | * Contains nested attributes for address family specific attributes. | ||
86 | * Each address family may create a attribute with the address family | ||
87 | * number as type and create its own attribute structure in it. | ||
88 | * | ||
89 | * Example: | ||
90 | * [IFLA_AF_SPEC] = { | ||
91 | * [AF_INET] = { | ||
92 | * [IFLA_INET_CONF] = ..., | ||
93 | * }, | ||
94 | * [AF_INET6] = { | ||
95 | * [IFLA_INET6_FLAGS] = ..., | ||
96 | * [IFLA_INET6_CONF] = ..., | ||
97 | * } | ||
98 | * } | ||
99 | */ | ||
100 | |||
83 | enum { | 101 | enum { |
84 | IFLA_UNSPEC, | 102 | IFLA_UNSPEC, |
85 | IFLA_ADDRESS, | 103 | IFLA_ADDRESS, |
@@ -116,6 +134,7 @@ enum { | |||
116 | IFLA_STATS64, | 134 | IFLA_STATS64, |
117 | IFLA_VF_PORTS, | 135 | IFLA_VF_PORTS, |
118 | IFLA_PORT_SELF, | 136 | IFLA_PORT_SELF, |
137 | IFLA_AF_SPEC, | ||
119 | __IFLA_MAX | 138 | __IFLA_MAX |
120 | }; | 139 | }; |
121 | 140 | ||
diff --git a/include/net/rtnetlink.h b/include/net/rtnetlink.h index e013c68bfb00..35be0bbcd7da 100644 --- a/include/net/rtnetlink.h +++ b/include/net/rtnetlink.h | |||
@@ -83,6 +83,37 @@ extern void __rtnl_link_unregister(struct rtnl_link_ops *ops); | |||
83 | extern int rtnl_link_register(struct rtnl_link_ops *ops); | 83 | extern int rtnl_link_register(struct rtnl_link_ops *ops); |
84 | extern void rtnl_link_unregister(struct rtnl_link_ops *ops); | 84 | extern void rtnl_link_unregister(struct rtnl_link_ops *ops); |
85 | 85 | ||
86 | /** | ||
87 | * struct rtnl_af_ops - rtnetlink address family operations | ||
88 | * | ||
89 | * @list: Used internally | ||
90 | * @family: Address family | ||
91 | * @fill_link_af: Function to fill IFLA_AF_SPEC with address family | ||
92 | * specific netlink attributes. | ||
93 | * @get_link_af_size: Function to calculate size of address family specific | ||
94 | * netlink attributes exlusive the container attribute. | ||
95 | * @parse_link_af: Function to parse a IFLA_AF_SPEC attribute and modify | ||
96 | * net_device accordingly. | ||
97 | */ | ||
98 | struct rtnl_af_ops { | ||
99 | struct list_head list; | ||
100 | int family; | ||
101 | |||
102 | int (*fill_link_af)(struct sk_buff *skb, | ||
103 | const struct net_device *dev); | ||
104 | size_t (*get_link_af_size)(const struct net_device *dev); | ||
105 | |||
106 | int (*parse_link_af)(struct net_device *dev, | ||
107 | const struct nlattr *attr); | ||
108 | }; | ||
109 | |||
110 | extern int __rtnl_af_register(struct rtnl_af_ops *ops); | ||
111 | extern void __rtnl_af_unregister(struct rtnl_af_ops *ops); | ||
112 | |||
113 | extern int rtnl_af_register(struct rtnl_af_ops *ops); | ||
114 | extern void rtnl_af_unregister(struct rtnl_af_ops *ops); | ||
115 | |||
116 | |||
86 | extern struct net *rtnl_link_get_net(struct net *src_net, struct nlattr *tb[]); | 117 | extern struct net *rtnl_link_get_net(struct net *src_net, struct nlattr *tb[]); |
87 | extern struct net_device *rtnl_create_link(struct net *src_net, struct net *net, | 118 | extern struct net_device *rtnl_create_link(struct net *src_net, struct net *net, |
88 | char *ifname, const struct rtnl_link_ops *ops, struct nlattr *tb[]); | 119 | char *ifname, const struct rtnl_link_ops *ops, struct nlattr *tb[]); |