| 1 | /* SPDX-License-Identifier: GPL-2.0 */ | 
|---|
| 2 | #ifndef __NET_RTNETLINK_H | 
|---|
| 3 | #define __NET_RTNETLINK_H | 
|---|
| 4 |  | 
|---|
| 5 | #include <linux/rtnetlink.h> | 
|---|
| 6 | #include <linux/srcu.h> | 
|---|
| 7 | #include <net/netlink.h> | 
|---|
| 8 |  | 
|---|
| 9 | typedef int (*rtnl_doit_func)(struct sk_buff *, struct nlmsghdr *, | 
|---|
| 10 | struct netlink_ext_ack *); | 
|---|
| 11 | typedef int (*rtnl_dumpit_func)(struct sk_buff *, struct netlink_callback *); | 
|---|
| 12 |  | 
|---|
| 13 | enum rtnl_link_flags { | 
|---|
| 14 | RTNL_FLAG_DOIT_UNLOCKED		= BIT(0), | 
|---|
| 15 | #define RTNL_FLAG_DOIT_PERNET		RTNL_FLAG_DOIT_UNLOCKED | 
|---|
| 16 | #define RTNL_FLAG_DOIT_PERNET_WIP	RTNL_FLAG_DOIT_UNLOCKED | 
|---|
| 17 | RTNL_FLAG_BULK_DEL_SUPPORTED	= BIT(1), | 
|---|
| 18 | RTNL_FLAG_DUMP_UNLOCKED		= BIT(2), | 
|---|
| 19 | RTNL_FLAG_DUMP_SPLIT_NLM_DONE	= BIT(3),	/* legacy behavior */ | 
|---|
| 20 | }; | 
|---|
| 21 |  | 
|---|
| 22 | enum rtnl_kinds { | 
|---|
| 23 | RTNL_KIND_NEW, | 
|---|
| 24 | RTNL_KIND_DEL, | 
|---|
| 25 | RTNL_KIND_GET, | 
|---|
| 26 | RTNL_KIND_SET | 
|---|
| 27 | }; | 
|---|
| 28 | #define RTNL_KIND_MASK 0x3 | 
|---|
| 29 |  | 
|---|
| 30 | static inline enum rtnl_kinds rtnl_msgtype_kind(int msgtype) | 
|---|
| 31 | { | 
|---|
| 32 | return msgtype & RTNL_KIND_MASK; | 
|---|
| 33 | } | 
|---|
| 34 |  | 
|---|
| 35 | /** | 
|---|
| 36 | *	struct rtnl_msg_handler - rtnetlink message type and handlers | 
|---|
| 37 | * | 
|---|
| 38 | *	@owner: NULL for built-in, THIS_MODULE for module | 
|---|
| 39 | *	@protocol: Protocol family or PF_UNSPEC | 
|---|
| 40 | *	@msgtype: rtnetlink message type | 
|---|
| 41 | *	@doit: Function pointer called for each request message | 
|---|
| 42 | *	@dumpit: Function pointer called for each dump request (NLM_F_DUMP) message | 
|---|
| 43 | *	@flags: rtnl_link_flags to modify behaviour of doit/dumpit functions | 
|---|
| 44 | */ | 
|---|
| 45 | struct rtnl_msg_handler { | 
|---|
| 46 | struct module *owner; | 
|---|
| 47 | int protocol; | 
|---|
| 48 | int msgtype; | 
|---|
| 49 | rtnl_doit_func doit; | 
|---|
| 50 | rtnl_dumpit_func dumpit; | 
|---|
| 51 | int flags; | 
|---|
| 52 | }; | 
|---|
| 53 |  | 
|---|
| 54 | void rtnl_unregister_all(int protocol); | 
|---|
| 55 |  | 
|---|
| 56 | int __rtnl_register_many(const struct rtnl_msg_handler *handlers, int n); | 
|---|
| 57 | void __rtnl_unregister_many(const struct rtnl_msg_handler *handlers, int n); | 
|---|
| 58 |  | 
|---|
| 59 | #define rtnl_register_many(handlers)				\ | 
|---|
| 60 | __rtnl_register_many(handlers, ARRAY_SIZE(handlers)) | 
|---|
| 61 | #define rtnl_unregister_many(handlers)				\ | 
|---|
| 62 | __rtnl_unregister_many(handlers, ARRAY_SIZE(handlers)) | 
|---|
| 63 |  | 
|---|
| 64 | static inline int rtnl_msg_family(const struct nlmsghdr *nlh) | 
|---|
| 65 | { | 
|---|
| 66 | if (nlmsg_len(nlh) >= sizeof(struct rtgenmsg)) | 
|---|
| 67 | return ((struct rtgenmsg *) nlmsg_data(nlh))->rtgen_family; | 
|---|
| 68 | else | 
|---|
| 69 | return AF_UNSPEC; | 
|---|
| 70 | } | 
|---|
| 71 |  | 
|---|
| 72 | /** | 
|---|
| 73 | * struct rtnl_newlink_params - parameters of rtnl_link_ops::newlink() | 
|---|
| 74 | * | 
|---|
| 75 | * @src_net: Source netns of rtnetlink socket | 
|---|
| 76 | * @link_net: Link netns by IFLA_LINK_NETNSID, NULL if not specified | 
|---|
| 77 | * @peer_net: Peer netns | 
|---|
| 78 | * @tb: IFLA_* attributes | 
|---|
| 79 | * @data: IFLA_INFO_DATA attributes | 
|---|
| 80 | */ | 
|---|
| 81 | struct rtnl_newlink_params { | 
|---|
| 82 | struct net *src_net; | 
|---|
| 83 | struct net *link_net; | 
|---|
| 84 | struct net *peer_net; | 
|---|
| 85 | struct nlattr **tb; | 
|---|
| 86 | struct nlattr **data; | 
|---|
| 87 | }; | 
|---|
| 88 |  | 
|---|
| 89 | /* Get effective link netns from newlink params. Generally, this is link_net | 
|---|
| 90 | * and falls back to src_net. But for compatibility, a driver may * choose to | 
|---|
| 91 | * use dev_net(dev) instead. | 
|---|
| 92 | */ | 
|---|
| 93 | static inline struct net *rtnl_newlink_link_net(struct rtnl_newlink_params *p) | 
|---|
| 94 | { | 
|---|
| 95 | return p->link_net ? : p->src_net; | 
|---|
| 96 | } | 
|---|
| 97 |  | 
|---|
| 98 | /* Get peer netns from newlink params. Fallback to link netns if peer netns is | 
|---|
| 99 | * not specified explicitly. | 
|---|
| 100 | */ | 
|---|
| 101 | static inline struct net *rtnl_newlink_peer_net(struct rtnl_newlink_params *p) | 
|---|
| 102 | { | 
|---|
| 103 | return p->peer_net ? : rtnl_newlink_link_net(p); | 
|---|
| 104 | } | 
|---|
| 105 |  | 
|---|
| 106 | /** | 
|---|
| 107 | *	struct rtnl_link_ops - rtnetlink link operations | 
|---|
| 108 | * | 
|---|
| 109 | *	@list: Used internally, protected by link_ops_mutex and SRCU | 
|---|
| 110 | *	@srcu: Used internally | 
|---|
| 111 | *	@kind: Identifier | 
|---|
| 112 | *	@netns_refund: Physical device, move to init_net on netns exit | 
|---|
| 113 | *	@peer_type: Peer device specific netlink attribute number (e.g. VETH_INFO_PEER) | 
|---|
| 114 | *	@maxtype: Highest device specific netlink attribute number | 
|---|
| 115 | *	@policy: Netlink policy for device specific attribute validation | 
|---|
| 116 | *	@validate: Optional validation function for netlink/changelink parameters | 
|---|
| 117 | *	@alloc: netdev allocation function, can be %NULL and is then used | 
|---|
| 118 | *		in place of alloc_netdev_mqs(), in this case @priv_size | 
|---|
| 119 | *		and @setup are unused. Returns a netdev or ERR_PTR(). | 
|---|
| 120 | *	@priv_size: sizeof net_device private space | 
|---|
| 121 | *	@setup: net_device setup function | 
|---|
| 122 | *	@newlink: Function for configuring and registering a new device | 
|---|
| 123 | *	@changelink: Function for changing parameters of an existing device | 
|---|
| 124 | *	@dellink: Function to remove a device | 
|---|
| 125 | *	@get_size: Function to calculate required room for dumping device | 
|---|
| 126 | *		   specific netlink attributes | 
|---|
| 127 | *	@fill_info: Function to dump device specific netlink attributes | 
|---|
| 128 | *	@get_xstats_size: Function to calculate required room for dumping device | 
|---|
| 129 | *			  specific statistics | 
|---|
| 130 | *	@fill_xstats: Function to dump device specific statistics | 
|---|
| 131 | *	@get_num_tx_queues: Function to determine number of transmit queues | 
|---|
| 132 | *			    to create when creating a new device. | 
|---|
| 133 | *	@get_num_rx_queues: Function to determine number of receive queues | 
|---|
| 134 | *			    to create when creating a new device. | 
|---|
| 135 | *	@get_link_net: Function to get the i/o netns of the device | 
|---|
| 136 | *	@get_linkxstats_size: Function to calculate the required room for | 
|---|
| 137 | *			      dumping device-specific extended link stats | 
|---|
| 138 | *	@fill_linkxstats: Function to dump device-specific extended link stats | 
|---|
| 139 | */ | 
|---|
| 140 | struct rtnl_link_ops { | 
|---|
| 141 | struct list_head	list; | 
|---|
| 142 | struct srcu_struct	srcu; | 
|---|
| 143 |  | 
|---|
| 144 | const char		*kind; | 
|---|
| 145 |  | 
|---|
| 146 | size_t			priv_size; | 
|---|
| 147 | struct net_device	*(*alloc)(struct nlattr *tb[], | 
|---|
| 148 | const char *ifname, | 
|---|
| 149 | unsigned char name_assign_type, | 
|---|
| 150 | unsigned int num_tx_queues, | 
|---|
| 151 | unsigned int num_rx_queues); | 
|---|
| 152 | void			(*setup)(struct net_device *dev); | 
|---|
| 153 |  | 
|---|
| 154 | bool			netns_refund; | 
|---|
| 155 | const u16		peer_type; | 
|---|
| 156 | unsigned int		maxtype; | 
|---|
| 157 | const struct nla_policy	*policy; | 
|---|
| 158 | int			(*validate)(struct nlattr *tb[], | 
|---|
| 159 | struct nlattr *data[], | 
|---|
| 160 | struct netlink_ext_ack *extack); | 
|---|
| 161 |  | 
|---|
| 162 | int			(*newlink)(struct net_device *dev, | 
|---|
| 163 | struct rtnl_newlink_params *params, | 
|---|
| 164 | struct netlink_ext_ack *extack); | 
|---|
| 165 | int			(*changelink)(struct net_device *dev, | 
|---|
| 166 | struct nlattr *tb[], | 
|---|
| 167 | struct nlattr *data[], | 
|---|
| 168 | struct netlink_ext_ack *extack); | 
|---|
| 169 | void			(*dellink)(struct net_device *dev, | 
|---|
| 170 | struct list_head *head); | 
|---|
| 171 |  | 
|---|
| 172 | size_t			(*get_size)(const struct net_device *dev); | 
|---|
| 173 | int			(*fill_info)(struct sk_buff *skb, | 
|---|
| 174 | const struct net_device *dev); | 
|---|
| 175 |  | 
|---|
| 176 | size_t			(*get_xstats_size)(const struct net_device *dev); | 
|---|
| 177 | int			(*fill_xstats)(struct sk_buff *skb, | 
|---|
| 178 | const struct net_device *dev); | 
|---|
| 179 | unsigned int		(*get_num_tx_queues)(void); | 
|---|
| 180 | unsigned int		(*get_num_rx_queues)(void); | 
|---|
| 181 |  | 
|---|
| 182 | unsigned int		slave_maxtype; | 
|---|
| 183 | const struct nla_policy	*slave_policy; | 
|---|
| 184 | int			(*slave_changelink)(struct net_device *dev, | 
|---|
| 185 | struct net_device *slave_dev, | 
|---|
| 186 | struct nlattr *tb[], | 
|---|
| 187 | struct nlattr *data[], | 
|---|
| 188 | struct netlink_ext_ack *extack); | 
|---|
| 189 | size_t			(*get_slave_size)(const struct net_device *dev, | 
|---|
| 190 | const struct net_device *slave_dev); | 
|---|
| 191 | int			(*fill_slave_info)(struct sk_buff *skb, | 
|---|
| 192 | const struct net_device *dev, | 
|---|
| 193 | const struct net_device *slave_dev); | 
|---|
| 194 | struct net		*(*get_link_net)(const struct net_device *dev); | 
|---|
| 195 | size_t			(*get_linkxstats_size)(const struct net_device *dev, | 
|---|
| 196 | int attr); | 
|---|
| 197 | int			(*fill_linkxstats)(struct sk_buff *skb, | 
|---|
| 198 | const struct net_device *dev, | 
|---|
| 199 | int *prividx, int attr); | 
|---|
| 200 | }; | 
|---|
| 201 |  | 
|---|
| 202 | int rtnl_link_register(struct rtnl_link_ops *ops); | 
|---|
| 203 | void rtnl_link_unregister(struct rtnl_link_ops *ops); | 
|---|
| 204 |  | 
|---|
| 205 | /** | 
|---|
| 206 | * 	struct rtnl_af_ops - rtnetlink address family operations | 
|---|
| 207 | * | 
|---|
| 208 | *	@list: Used internally, protected by RTNL and SRCU | 
|---|
| 209 | *	@srcu: Used internally | 
|---|
| 210 | * 	@family: Address family | 
|---|
| 211 | * 	@fill_link_af: Function to fill IFLA_AF_SPEC with address family | 
|---|
| 212 | * 		       specific netlink attributes. | 
|---|
| 213 | * 	@get_link_af_size: Function to calculate size of address family specific | 
|---|
| 214 | * 			   netlink attributes. | 
|---|
| 215 | *	@validate_link_af: Validate a IFLA_AF_SPEC attribute, must check attr | 
|---|
| 216 | *			   for invalid configuration settings. | 
|---|
| 217 | * 	@set_link_af: Function to parse a IFLA_AF_SPEC attribute and modify | 
|---|
| 218 | *		      net_device accordingly. | 
|---|
| 219 | */ | 
|---|
| 220 | struct rtnl_af_ops { | 
|---|
| 221 | struct list_head	list; | 
|---|
| 222 | struct srcu_struct	srcu; | 
|---|
| 223 |  | 
|---|
| 224 | int			family; | 
|---|
| 225 |  | 
|---|
| 226 | int			(*fill_link_af)(struct sk_buff *skb, | 
|---|
| 227 | const struct net_device *dev, | 
|---|
| 228 | u32 ext_filter_mask); | 
|---|
| 229 | size_t			(*get_link_af_size)(const struct net_device *dev, | 
|---|
| 230 | u32 ext_filter_mask); | 
|---|
| 231 |  | 
|---|
| 232 | int			(*validate_link_af)(const struct net_device *dev, | 
|---|
| 233 | const struct nlattr *attr, | 
|---|
| 234 | struct netlink_ext_ack *extack); | 
|---|
| 235 | int			(*set_link_af)(struct net_device *dev, | 
|---|
| 236 | const struct nlattr *attr, | 
|---|
| 237 | struct netlink_ext_ack *extack); | 
|---|
| 238 | int			(*fill_stats_af)(struct sk_buff *skb, | 
|---|
| 239 | const struct net_device *dev); | 
|---|
| 240 | size_t			(*get_stats_af_size)(const struct net_device *dev); | 
|---|
| 241 | }; | 
|---|
| 242 |  | 
|---|
| 243 | int rtnl_af_register(struct rtnl_af_ops *ops); | 
|---|
| 244 | void rtnl_af_unregister(struct rtnl_af_ops *ops); | 
|---|
| 245 |  | 
|---|
| 246 | struct net *rtnl_link_get_net(struct net *src_net, struct nlattr *tb[]); | 
|---|
| 247 | struct net_device *rtnl_create_link(struct net *net, const char *ifname, | 
|---|
| 248 | unsigned char name_assign_type, | 
|---|
| 249 | const struct rtnl_link_ops *ops, | 
|---|
| 250 | struct nlattr *tb[], | 
|---|
| 251 | struct netlink_ext_ack *extack); | 
|---|
| 252 | int rtnl_delete_link(struct net_device *dev, u32 portid, const struct nlmsghdr *nlh); | 
|---|
| 253 | int rtnl_configure_link(struct net_device *dev, const struct ifinfomsg *ifm, | 
|---|
| 254 | u32 portid, const struct nlmsghdr *nlh); | 
|---|
| 255 |  | 
|---|
| 256 | int rtnl_nla_parse_ifinfomsg(struct nlattr **tb, const struct nlattr *nla_peer, | 
|---|
| 257 | struct netlink_ext_ack *exterr); | 
|---|
| 258 | struct net *rtnl_get_net_ns_capable(struct sock *sk, int netnsid); | 
|---|
| 259 |  | 
|---|
| 260 | #define MODULE_ALIAS_RTNL_LINK(kind) MODULE_ALIAS("rtnl-link-" kind) | 
|---|
| 261 |  | 
|---|
| 262 | #endif | 
|---|
| 263 |  | 
|---|