rtnetlink.c (54156da8937c9f5f84b4215e239a61ecc7c29275) | rtnetlink.c (b2d3bcfa26a7a8de41f358a6cae8b848673b3c6e) |
---|---|
1/* 2 * INET An implementation of the TCP/IP protocol suite for the LINUX 3 * operating system. INET is implemented using the BSD Socket 4 * interface as the means of communication with the user level. 5 * 6 * Routing netlink socket interface: protocol independent part. 7 * 8 * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> --- 48 unchanged lines hidden (view full) --- 57#include <net/pkt_sched.h> 58#include <net/fib_rules.h> 59#include <net/rtnetlink.h> 60#include <net/net_namespace.h> 61 62struct rtnl_link { 63 rtnl_doit_func doit; 64 rtnl_dumpit_func dumpit; | 1/* 2 * INET An implementation of the TCP/IP protocol suite for the LINUX 3 * operating system. INET is implemented using the BSD Socket 4 * interface as the means of communication with the user level. 5 * 6 * Routing netlink socket interface: protocol independent part. 7 * 8 * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> --- 48 unchanged lines hidden (view full) --- 57#include <net/pkt_sched.h> 58#include <net/fib_rules.h> 59#include <net/rtnetlink.h> 60#include <net/net_namespace.h> 61 62struct rtnl_link { 63 rtnl_doit_func doit; 64 rtnl_dumpit_func dumpit; |
65 struct module *owner; |
|
65 unsigned int flags; | 66 unsigned int flags; |
67 struct rcu_head rcu; |
|
66}; 67 68static DEFINE_MUTEX(rtnl_mutex); 69 70void rtnl_lock(void) 71{ 72 mutex_lock(&rtnl_mutex); 73} --- 48 unchanged lines hidden (view full) --- 122#ifdef CONFIG_PROVE_LOCKING 123bool lockdep_rtnl_is_held(void) 124{ 125 return lockdep_is_held(&rtnl_mutex); 126} 127EXPORT_SYMBOL(lockdep_rtnl_is_held); 128#endif /* #ifdef CONFIG_PROVE_LOCKING */ 129 | 68}; 69 70static DEFINE_MUTEX(rtnl_mutex); 71 72void rtnl_lock(void) 73{ 74 mutex_lock(&rtnl_mutex); 75} --- 48 unchanged lines hidden (view full) --- 124#ifdef CONFIG_PROVE_LOCKING 125bool lockdep_rtnl_is_held(void) 126{ 127 return lockdep_is_held(&rtnl_mutex); 128} 129EXPORT_SYMBOL(lockdep_rtnl_is_held); 130#endif /* #ifdef CONFIG_PROVE_LOCKING */ 131 |
130static struct rtnl_link __rcu *rtnl_msg_handlers[RTNL_FAMILY_MAX + 1]; 131static refcount_t rtnl_msg_handlers_ref[RTNL_FAMILY_MAX + 1]; | 132static struct rtnl_link *__rcu *rtnl_msg_handlers[RTNL_FAMILY_MAX + 1]; |
132 133static inline int rtm_msgindex(int msgtype) 134{ 135 int msgindex = msgtype - RTM_BASE; 136 137 /* 138 * msgindex < 0 implies someone tried to register a netlink 139 * control code. msgindex >= RTM_NR_MSGTYPES may indicate that 140 * the message type has not been added to linux/rtnetlink.h 141 */ 142 BUG_ON(msgindex < 0 || msgindex >= RTM_NR_MSGTYPES); 143 144 return msgindex; 145} 146 | 133 134static inline int rtm_msgindex(int msgtype) 135{ 136 int msgindex = msgtype - RTM_BASE; 137 138 /* 139 * msgindex < 0 implies someone tried to register a netlink 140 * control code. msgindex >= RTM_NR_MSGTYPES may indicate that 141 * the message type has not been added to linux/rtnetlink.h 142 */ 143 BUG_ON(msgindex < 0 || msgindex >= RTM_NR_MSGTYPES); 144 145 return msgindex; 146} 147 |
147/** 148 * __rtnl_register - Register a rtnetlink message type 149 * @protocol: Protocol family or PF_UNSPEC 150 * @msgtype: rtnetlink message type 151 * @doit: Function pointer called for each request message 152 * @dumpit: Function pointer called for each dump request (NLM_F_DUMP) message 153 * @flags: rtnl_link_flags to modifiy behaviour of doit/dumpit functions 154 * 155 * Registers the specified function pointers (at least one of them has 156 * to be non-NULL) to be called whenever a request message for the 157 * specified protocol family and message type is received. 158 * 159 * The special protocol family PF_UNSPEC may be used to define fallback 160 * function pointers for the case when no entry for the specific protocol 161 * family exists. 162 * 163 * Returns 0 on success or a negative error code. 164 */ 165int __rtnl_register(int protocol, int msgtype, 166 rtnl_doit_func doit, rtnl_dumpit_func dumpit, 167 unsigned int flags) | 148static struct rtnl_link *rtnl_get_link(int protocol, int msgtype) |
168{ | 149{ |
169 struct rtnl_link *tab; | 150 struct rtnl_link **tab; 151 152 if (protocol >= ARRAY_SIZE(rtnl_msg_handlers)) 153 protocol = PF_UNSPEC; 154 155 tab = rcu_dereference_rtnl(rtnl_msg_handlers[protocol]); 156 if (!tab) 157 tab = rcu_dereference_rtnl(rtnl_msg_handlers[PF_UNSPEC]); 158 159 return tab[msgtype]; 160} 161 162static int rtnl_register_internal(struct module *owner, 163 int protocol, int msgtype, 164 rtnl_doit_func doit, rtnl_dumpit_func dumpit, 165 unsigned int flags) 166{ 167 struct rtnl_link *link, *old; 168 struct rtnl_link __rcu **tab; |
170 int msgindex; | 169 int msgindex; |
170 int ret = -ENOBUFS; |
|
171 172 BUG_ON(protocol < 0 || protocol > RTNL_FAMILY_MAX); 173 msgindex = rtm_msgindex(msgtype); 174 | 171 172 BUG_ON(protocol < 0 || protocol > RTNL_FAMILY_MAX); 173 msgindex = rtm_msgindex(msgtype); 174 |
175 tab = rcu_dereference_raw(rtnl_msg_handlers[protocol]); | 175 rtnl_lock(); 176 tab = rtnl_msg_handlers[protocol]; |
176 if (tab == NULL) { | 177 if (tab == NULL) { |
177 tab = kcalloc(RTM_NR_MSGTYPES, sizeof(*tab), GFP_KERNEL); 178 if (tab == NULL) 179 return -ENOBUFS; | 178 tab = kcalloc(RTM_NR_MSGTYPES, sizeof(void *), GFP_KERNEL); 179 if (!tab) 180 goto unlock; |
180 | 181 |
182 /* ensures we see the 0 stores */ |
|
181 rcu_assign_pointer(rtnl_msg_handlers[protocol], tab); 182 } 183 | 183 rcu_assign_pointer(rtnl_msg_handlers[protocol], tab); 184 } 185 |
186 old = rtnl_dereference(tab[msgindex]); 187 if (old) { 188 link = kmemdup(old, sizeof(*old), GFP_KERNEL); 189 if (!link) 190 goto unlock; 191 } else { 192 link = kzalloc(sizeof(*link), GFP_KERNEL); 193 if (!link) 194 goto unlock; 195 } 196 197 WARN_ON(link->owner && link->owner != owner); 198 link->owner = owner; 199 200 WARN_ON(doit && link->doit && link->doit != doit); |
|
184 if (doit) | 201 if (doit) |
185 tab[msgindex].doit = doit; | 202 link->doit = doit; 203 WARN_ON(dumpit && link->dumpit && link->dumpit != dumpit); |
186 if (dumpit) | 204 if (dumpit) |
187 tab[msgindex].dumpit = dumpit; 188 tab[msgindex].flags |= flags; | 205 link->dumpit = dumpit; |
189 | 206 |
190 return 0; | 207 link->flags |= flags; 208 209 /* publish protocol:msgtype */ 210 rcu_assign_pointer(tab[msgindex], link); 211 ret = 0; 212 if (old) 213 kfree_rcu(old, rcu); 214unlock: 215 rtnl_unlock(); 216 return ret; |
191} | 217} |
192EXPORT_SYMBOL_GPL(__rtnl_register); | |
193 194/** | 218 219/** |
220 * rtnl_register_module - Register a rtnetlink message type 221 * 222 * @owner: module registering the hook (THIS_MODULE) 223 * @protocol: Protocol family or PF_UNSPEC 224 * @msgtype: rtnetlink message type 225 * @doit: Function pointer called for each request message 226 * @dumpit: Function pointer called for each dump request (NLM_F_DUMP) message 227 * @flags: rtnl_link_flags to modifiy behaviour of doit/dumpit functions 228 * 229 * Like rtnl_register, but for use by removable modules. 230 */ 231int rtnl_register_module(struct module *owner, 232 int protocol, int msgtype, 233 rtnl_doit_func doit, rtnl_dumpit_func dumpit, 234 unsigned int flags) 235{ 236 return rtnl_register_internal(owner, protocol, msgtype, 237 doit, dumpit, flags); 238} 239EXPORT_SYMBOL_GPL(rtnl_register_module); 240 241/** |
|
195 * rtnl_register - Register a rtnetlink message type | 242 * rtnl_register - Register a rtnetlink message type |
243 * @protocol: Protocol family or PF_UNSPEC 244 * @msgtype: rtnetlink message type 245 * @doit: Function pointer called for each request message 246 * @dumpit: Function pointer called for each dump request (NLM_F_DUMP) message 247 * @flags: rtnl_link_flags to modifiy behaviour of doit/dumpit functions |
|
196 * | 248 * |
197 * Identical to __rtnl_register() but panics on failure. This is useful 198 * as failure of this function is very unlikely, it can only happen due 199 * to lack of memory when allocating the chain to store all message 200 * handlers for a protocol. Meant for use in init functions where lack 201 * of memory implies no sense in continuing. | 249 * Registers the specified function pointers (at least one of them has 250 * to be non-NULL) to be called whenever a request message for the 251 * specified protocol family and message type is received. 252 * 253 * The special protocol family PF_UNSPEC may be used to define fallback 254 * function pointers for the case when no entry for the specific protocol 255 * family exists. |
202 */ 203void rtnl_register(int protocol, int msgtype, 204 rtnl_doit_func doit, rtnl_dumpit_func dumpit, 205 unsigned int flags) 206{ | 256 */ 257void rtnl_register(int protocol, int msgtype, 258 rtnl_doit_func doit, rtnl_dumpit_func dumpit, 259 unsigned int flags) 260{ |
207 if (__rtnl_register(protocol, msgtype, doit, dumpit, flags) < 0) 208 panic("Unable to register rtnetlink message handler, " 209 "protocol = %d, message type = %d\n", 210 protocol, msgtype); | 261 int err; 262 263 err = rtnl_register_internal(NULL, protocol, msgtype, doit, dumpit, 264 flags); 265 if (err) 266 pr_err("Unable to register rtnetlink message handler, " 267 "protocol = %d, message type = %d\n", protocol, msgtype); |
211} | 268} |
212EXPORT_SYMBOL_GPL(rtnl_register); | |
213 214/** 215 * rtnl_unregister - Unregister a rtnetlink message type 216 * @protocol: Protocol family or PF_UNSPEC 217 * @msgtype: rtnetlink message type 218 * 219 * Returns 0 on success or a negative error code. 220 */ 221int rtnl_unregister(int protocol, int msgtype) 222{ | 269 270/** 271 * rtnl_unregister - Unregister a rtnetlink message type 272 * @protocol: Protocol family or PF_UNSPEC 273 * @msgtype: rtnetlink message type 274 * 275 * Returns 0 on success or a negative error code. 276 */ 277int rtnl_unregister(int protocol, int msgtype) 278{ |
223 struct rtnl_link *handlers; | 279 struct rtnl_link **tab, *link; |
224 int msgindex; 225 226 BUG_ON(protocol < 0 || protocol > RTNL_FAMILY_MAX); 227 msgindex = rtm_msgindex(msgtype); 228 229 rtnl_lock(); | 280 int msgindex; 281 282 BUG_ON(protocol < 0 || protocol > RTNL_FAMILY_MAX); 283 msgindex = rtm_msgindex(msgtype); 284 285 rtnl_lock(); |
230 handlers = rtnl_dereference(rtnl_msg_handlers[protocol]); 231 if (!handlers) { | 286 tab = rtnl_dereference(rtnl_msg_handlers[protocol]); 287 if (!tab) { |
232 rtnl_unlock(); 233 return -ENOENT; 234 } 235 | 288 rtnl_unlock(); 289 return -ENOENT; 290 } 291 |
236 handlers[msgindex].doit = NULL; 237 handlers[msgindex].dumpit = NULL; 238 handlers[msgindex].flags = 0; | 292 link = tab[msgindex]; 293 rcu_assign_pointer(tab[msgindex], NULL); |
239 rtnl_unlock(); 240 | 294 rtnl_unlock(); 295 |
296 kfree_rcu(link, rcu); 297 |
|
241 return 0; 242} 243EXPORT_SYMBOL_GPL(rtnl_unregister); 244 245/** 246 * rtnl_unregister_all - Unregister all rtnetlink message type of a protocol 247 * @protocol : Protocol family or PF_UNSPEC 248 * 249 * Identical to calling rtnl_unregster() for all registered message types 250 * of a certain protocol family. 251 */ 252void rtnl_unregister_all(int protocol) 253{ | 298 return 0; 299} 300EXPORT_SYMBOL_GPL(rtnl_unregister); 301 302/** 303 * rtnl_unregister_all - Unregister all rtnetlink message type of a protocol 304 * @protocol : Protocol family or PF_UNSPEC 305 * 306 * Identical to calling rtnl_unregster() for all registered message types 307 * of a certain protocol family. 308 */ 309void rtnl_unregister_all(int protocol) 310{ |
254 struct rtnl_link *handlers; | 311 struct rtnl_link **tab, *link; 312 int msgindex; |
255 256 BUG_ON(protocol < 0 || protocol > RTNL_FAMILY_MAX); 257 258 rtnl_lock(); | 313 314 BUG_ON(protocol < 0 || protocol > RTNL_FAMILY_MAX); 315 316 rtnl_lock(); |
259 handlers = rtnl_dereference(rtnl_msg_handlers[protocol]); | 317 tab = rtnl_msg_handlers[protocol]; |
260 RCU_INIT_POINTER(rtnl_msg_handlers[protocol], NULL); | 318 RCU_INIT_POINTER(rtnl_msg_handlers[protocol], NULL); |
319 for (msgindex = 0; msgindex < RTM_NR_MSGTYPES; msgindex++) { 320 link = tab[msgindex]; 321 if (!link) 322 continue; 323 324 rcu_assign_pointer(tab[msgindex], NULL); 325 kfree_rcu(link, rcu); 326 } |
|
261 rtnl_unlock(); 262 263 synchronize_net(); 264 | 327 rtnl_unlock(); 328 329 synchronize_net(); 330 |
265 while (refcount_read(&rtnl_msg_handlers_ref[protocol]) > 1) 266 schedule(); 267 kfree(handlers); | 331 kfree(tab); |
268} 269EXPORT_SYMBOL_GPL(rtnl_unregister_all); 270 271static LIST_HEAD(link_ops); 272 273static const struct rtnl_link_ops *rtnl_link_ops_get(const char *kind) 274{ 275 const struct rtnl_link_ops *ops; --- 559 unchanged lines hidden (view full) --- 835 /* IFLA_VF_STATS_RX_BYTES */ 836 nla_total_size_64bit(sizeof(__u64)) + 837 /* IFLA_VF_STATS_TX_BYTES */ 838 nla_total_size_64bit(sizeof(__u64)) + 839 /* IFLA_VF_STATS_BROADCAST */ 840 nla_total_size_64bit(sizeof(__u64)) + 841 /* IFLA_VF_STATS_MULTICAST */ 842 nla_total_size_64bit(sizeof(__u64)) + | 332} 333EXPORT_SYMBOL_GPL(rtnl_unregister_all); 334 335static LIST_HEAD(link_ops); 336 337static const struct rtnl_link_ops *rtnl_link_ops_get(const char *kind) 338{ 339 const struct rtnl_link_ops *ops; --- 559 unchanged lines hidden (view full) --- 899 /* IFLA_VF_STATS_RX_BYTES */ 900 nla_total_size_64bit(sizeof(__u64)) + 901 /* IFLA_VF_STATS_TX_BYTES */ 902 nla_total_size_64bit(sizeof(__u64)) + 903 /* IFLA_VF_STATS_BROADCAST */ 904 nla_total_size_64bit(sizeof(__u64)) + 905 /* IFLA_VF_STATS_MULTICAST */ 906 nla_total_size_64bit(sizeof(__u64)) + |
907 /* IFLA_VF_STATS_RX_DROPPED */ 908 nla_total_size_64bit(sizeof(__u64)) + 909 /* IFLA_VF_STATS_TX_DROPPED */ 910 nla_total_size_64bit(sizeof(__u64)) + |
|
843 nla_total_size(sizeof(struct ifla_vf_trust))); 844 return size; 845 } else 846 return 0; 847} 848 849static size_t rtnl_port_size(const struct net_device *dev, 850 u32 ext_filter_mask) --- 66 unchanged lines hidden (view full) --- 917 + nla_total_size(MAX_PHYS_ITEM_ID_LEN) /* IFLA_PHYS_PORT_ID */ 918 + nla_total_size(MAX_PHYS_ITEM_ID_LEN) /* IFLA_PHYS_SWITCH_ID */ 919 + nla_total_size(IFNAMSIZ) /* IFLA_PHYS_PORT_NAME */ 920 + rtnl_xdp_size() /* IFLA_XDP */ 921 + nla_total_size(4) /* IFLA_EVENT */ 922 + nla_total_size(4) /* IFLA_NEW_NETNSID */ 923 + nla_total_size(1) /* IFLA_PROTO_DOWN */ 924 + nla_total_size(4) /* IFLA_IF_NETNSID */ | 911 nla_total_size(sizeof(struct ifla_vf_trust))); 912 return size; 913 } else 914 return 0; 915} 916 917static size_t rtnl_port_size(const struct net_device *dev, 918 u32 ext_filter_mask) --- 66 unchanged lines hidden (view full) --- 985 + nla_total_size(MAX_PHYS_ITEM_ID_LEN) /* IFLA_PHYS_PORT_ID */ 986 + nla_total_size(MAX_PHYS_ITEM_ID_LEN) /* IFLA_PHYS_SWITCH_ID */ 987 + nla_total_size(IFNAMSIZ) /* IFLA_PHYS_PORT_NAME */ 988 + rtnl_xdp_size() /* IFLA_XDP */ 989 + nla_total_size(4) /* IFLA_EVENT */ 990 + nla_total_size(4) /* IFLA_NEW_NETNSID */ 991 + nla_total_size(1) /* IFLA_PROTO_DOWN */ 992 + nla_total_size(4) /* IFLA_IF_NETNSID */ |
993 + nla_total_size(4) /* IFLA_CARRIER_UP_COUNT */ 994 + nla_total_size(4) /* IFLA_CARRIER_DOWN_COUNT */ |
|
925 + 0; 926} 927 928static int rtnl_vf_ports_fill(struct sk_buff *skb, struct net_device *dev) 929{ 930 struct nlattr *vf_ports; 931 struct nlattr *vf_port; 932 int vf; --- 256 unchanged lines hidden (view full) --- 1189 vf_stats.tx_packets, IFLA_VF_STATS_PAD) || 1190 nla_put_u64_64bit(skb, IFLA_VF_STATS_RX_BYTES, 1191 vf_stats.rx_bytes, IFLA_VF_STATS_PAD) || 1192 nla_put_u64_64bit(skb, IFLA_VF_STATS_TX_BYTES, 1193 vf_stats.tx_bytes, IFLA_VF_STATS_PAD) || 1194 nla_put_u64_64bit(skb, IFLA_VF_STATS_BROADCAST, 1195 vf_stats.broadcast, IFLA_VF_STATS_PAD) || 1196 nla_put_u64_64bit(skb, IFLA_VF_STATS_MULTICAST, | 995 + 0; 996} 997 998static int rtnl_vf_ports_fill(struct sk_buff *skb, struct net_device *dev) 999{ 1000 struct nlattr *vf_ports; 1001 struct nlattr *vf_port; 1002 int vf; --- 256 unchanged lines hidden (view full) --- 1259 vf_stats.tx_packets, IFLA_VF_STATS_PAD) || 1260 nla_put_u64_64bit(skb, IFLA_VF_STATS_RX_BYTES, 1261 vf_stats.rx_bytes, IFLA_VF_STATS_PAD) || 1262 nla_put_u64_64bit(skb, IFLA_VF_STATS_TX_BYTES, 1263 vf_stats.tx_bytes, IFLA_VF_STATS_PAD) || 1264 nla_put_u64_64bit(skb, IFLA_VF_STATS_BROADCAST, 1265 vf_stats.broadcast, IFLA_VF_STATS_PAD) || 1266 nla_put_u64_64bit(skb, IFLA_VF_STATS_MULTICAST, |
1197 vf_stats.multicast, IFLA_VF_STATS_PAD)) { | 1267 vf_stats.multicast, IFLA_VF_STATS_PAD) || 1268 nla_put_u64_64bit(skb, IFLA_VF_STATS_RX_DROPPED, 1269 vf_stats.rx_dropped, IFLA_VF_STATS_PAD) || 1270 nla_put_u64_64bit(skb, IFLA_VF_STATS_TX_DROPPED, 1271 vf_stats.tx_dropped, IFLA_VF_STATS_PAD)) { |
1198 nla_nest_cancel(skb, vfstats); 1199 goto nla_put_vf_failure; 1200 } 1201 nla_nest_end(skb, vfstats); 1202 nla_nest_end(skb, vf); 1203 return 0; 1204 1205nla_put_vf_failure: --- 50 unchanged lines hidden (view full) --- 1256 1257 return 0; 1258} 1259 1260static u8 rtnl_xdp_attached_mode(struct net_device *dev, u32 *prog_id) 1261{ 1262 const struct net_device_ops *ops = dev->netdev_ops; 1263 const struct bpf_prog *generic_xdp_prog; | 1272 nla_nest_cancel(skb, vfstats); 1273 goto nla_put_vf_failure; 1274 } 1275 nla_nest_end(skb, vfstats); 1276 nla_nest_end(skb, vf); 1277 return 0; 1278 1279nla_put_vf_failure: --- 50 unchanged lines hidden (view full) --- 1330 1331 return 0; 1332} 1333 1334static u8 rtnl_xdp_attached_mode(struct net_device *dev, u32 *prog_id) 1335{ 1336 const struct net_device_ops *ops = dev->netdev_ops; 1337 const struct bpf_prog *generic_xdp_prog; |
1338 struct netdev_bpf xdp; |
|
1264 1265 ASSERT_RTNL(); 1266 1267 *prog_id = 0; 1268 generic_xdp_prog = rtnl_dereference(dev->xdp_prog); 1269 if (generic_xdp_prog) { 1270 *prog_id = generic_xdp_prog->aux->id; 1271 return XDP_ATTACHED_SKB; 1272 } 1273 if (!ops->ndo_bpf) 1274 return XDP_ATTACHED_NONE; 1275 | 1339 1340 ASSERT_RTNL(); 1341 1342 *prog_id = 0; 1343 generic_xdp_prog = rtnl_dereference(dev->xdp_prog); 1344 if (generic_xdp_prog) { 1345 *prog_id = generic_xdp_prog->aux->id; 1346 return XDP_ATTACHED_SKB; 1347 } 1348 if (!ops->ndo_bpf) 1349 return XDP_ATTACHED_NONE; 1350 |
1276 return __dev_xdp_attached(dev, ops->ndo_bpf, prog_id); | 1351 __dev_xdp_query(dev, ops->ndo_bpf, &xdp); 1352 *prog_id = xdp.prog_id; 1353 1354 return xdp.prog_attached; |
1277} 1278 1279static int rtnl_xdp_fill(struct sk_buff *skb, struct net_device *dev) 1280{ 1281 struct nlattr *xdp; 1282 u32 prog_id; 1283 int err; 1284 --- 185 unchanged lines hidden (view full) --- 1470#endif 1471 nla_put_iflink(skb, dev) || 1472 put_master_ifindex(skb, dev) || 1473 nla_put_u8(skb, IFLA_CARRIER, netif_carrier_ok(dev)) || 1474 (dev->qdisc && 1475 nla_put_string(skb, IFLA_QDISC, dev->qdisc->ops->id)) || 1476 nla_put_ifalias(skb, dev) || 1477 nla_put_u32(skb, IFLA_CARRIER_CHANGES, | 1355} 1356 1357static int rtnl_xdp_fill(struct sk_buff *skb, struct net_device *dev) 1358{ 1359 struct nlattr *xdp; 1360 u32 prog_id; 1361 int err; 1362 --- 185 unchanged lines hidden (view full) --- 1548#endif 1549 nla_put_iflink(skb, dev) || 1550 put_master_ifindex(skb, dev) || 1551 nla_put_u8(skb, IFLA_CARRIER, netif_carrier_ok(dev)) || 1552 (dev->qdisc && 1553 nla_put_string(skb, IFLA_QDISC, dev->qdisc->ops->id)) || 1554 nla_put_ifalias(skb, dev) || 1555 nla_put_u32(skb, IFLA_CARRIER_CHANGES, |
1478 atomic_read(&dev->carrier_changes)) || 1479 nla_put_u8(skb, IFLA_PROTO_DOWN, dev->proto_down)) | 1556 atomic_read(&dev->carrier_up_count) + 1557 atomic_read(&dev->carrier_down_count)) || 1558 nla_put_u8(skb, IFLA_PROTO_DOWN, dev->proto_down) || 1559 nla_put_u32(skb, IFLA_CARRIER_UP_COUNT, 1560 atomic_read(&dev->carrier_up_count)) || 1561 nla_put_u32(skb, IFLA_CARRIER_DOWN_COUNT, 1562 atomic_read(&dev->carrier_down_count))) |
1480 goto nla_put_failure; 1481 1482 if (event != IFLA_EVENT_NONE) { 1483 if (nla_put_u32(skb, IFLA_EVENT, event)) 1484 goto nla_put_failure; 1485 } 1486 1487 if (rtnl_fill_link_ifmap(skb, dev)) --- 76 unchanged lines hidden (view full) --- 1564 [IFLA_VFINFO_LIST] = {. type = NLA_NESTED }, 1565 [IFLA_VF_PORTS] = { .type = NLA_NESTED }, 1566 [IFLA_PORT_SELF] = { .type = NLA_NESTED }, 1567 [IFLA_AF_SPEC] = { .type = NLA_NESTED }, 1568 [IFLA_EXT_MASK] = { .type = NLA_U32 }, 1569 [IFLA_PROMISCUITY] = { .type = NLA_U32 }, 1570 [IFLA_NUM_TX_QUEUES] = { .type = NLA_U32 }, 1571 [IFLA_NUM_RX_QUEUES] = { .type = NLA_U32 }, | 1563 goto nla_put_failure; 1564 1565 if (event != IFLA_EVENT_NONE) { 1566 if (nla_put_u32(skb, IFLA_EVENT, event)) 1567 goto nla_put_failure; 1568 } 1569 1570 if (rtnl_fill_link_ifmap(skb, dev)) --- 76 unchanged lines hidden (view full) --- 1647 [IFLA_VFINFO_LIST] = {. type = NLA_NESTED }, 1648 [IFLA_VF_PORTS] = { .type = NLA_NESTED }, 1649 [IFLA_PORT_SELF] = { .type = NLA_NESTED }, 1650 [IFLA_AF_SPEC] = { .type = NLA_NESTED }, 1651 [IFLA_EXT_MASK] = { .type = NLA_U32 }, 1652 [IFLA_PROMISCUITY] = { .type = NLA_U32 }, 1653 [IFLA_NUM_TX_QUEUES] = { .type = NLA_U32 }, 1654 [IFLA_NUM_RX_QUEUES] = { .type = NLA_U32 }, |
1655 [IFLA_GSO_MAX_SEGS] = { .type = NLA_U32 }, 1656 [IFLA_GSO_MAX_SIZE] = { .type = NLA_U32 }, |
|
1572 [IFLA_PHYS_PORT_ID] = { .type = NLA_BINARY, .len = MAX_PHYS_ITEM_ID_LEN }, 1573 [IFLA_CARRIER_CHANGES] = { .type = NLA_U32 }, /* ignored */ 1574 [IFLA_PHYS_SWITCH_ID] = { .type = NLA_BINARY, .len = MAX_PHYS_ITEM_ID_LEN }, 1575 [IFLA_LINK_NETNSID] = { .type = NLA_S32 }, 1576 [IFLA_PROTO_DOWN] = { .type = NLA_U8 }, 1577 [IFLA_XDP] = { .type = NLA_NESTED }, 1578 [IFLA_EVENT] = { .type = NLA_U32 }, 1579 [IFLA_GROUP] = { .type = NLA_U32 }, 1580 [IFLA_IF_NETNSID] = { .type = NLA_S32 }, | 1657 [IFLA_PHYS_PORT_ID] = { .type = NLA_BINARY, .len = MAX_PHYS_ITEM_ID_LEN }, 1658 [IFLA_CARRIER_CHANGES] = { .type = NLA_U32 }, /* ignored */ 1659 [IFLA_PHYS_SWITCH_ID] = { .type = NLA_BINARY, .len = MAX_PHYS_ITEM_ID_LEN }, 1660 [IFLA_LINK_NETNSID] = { .type = NLA_S32 }, 1661 [IFLA_PROTO_DOWN] = { .type = NLA_U8 }, 1662 [IFLA_XDP] = { .type = NLA_NESTED }, 1663 [IFLA_EVENT] = { .type = NLA_U32 }, 1664 [IFLA_GROUP] = { .type = NLA_U32 }, 1665 [IFLA_IF_NETNSID] = { .type = NLA_S32 }, |
1666 [IFLA_CARRIER_UP_COUNT] = { .type = NLA_U32 }, 1667 [IFLA_CARRIER_DOWN_COUNT] = { .type = NLA_U32 }, |
|
1581}; 1582 1583static const struct nla_policy ifla_info_policy[IFLA_INFO_MAX+1] = { 1584 [IFLA_INFO_KIND] = { .type = NLA_STRING }, 1585 [IFLA_INFO_DATA] = { .type = NLA_NESTED }, 1586 [IFLA_INFO_SLAVE_KIND] = { .type = NLA_STRING }, 1587 [IFLA_INFO_SLAVE_DATA] = { .type = NLA_NESTED }, 1588}; --- 625 unchanged lines hidden (view full) --- 2214 if (err) { 2215 dev->tx_queue_len = orig_len; 2216 goto errout; 2217 } 2218 status |= DO_SETLINK_MODIFIED; 2219 } 2220 } 2221 | 1668}; 1669 1670static const struct nla_policy ifla_info_policy[IFLA_INFO_MAX+1] = { 1671 [IFLA_INFO_KIND] = { .type = NLA_STRING }, 1672 [IFLA_INFO_DATA] = { .type = NLA_NESTED }, 1673 [IFLA_INFO_SLAVE_KIND] = { .type = NLA_STRING }, 1674 [IFLA_INFO_SLAVE_DATA] = { .type = NLA_NESTED }, 1675}; --- 625 unchanged lines hidden (view full) --- 2301 if (err) { 2302 dev->tx_queue_len = orig_len; 2303 goto errout; 2304 } 2305 status |= DO_SETLINK_MODIFIED; 2306 } 2307 } 2308 |
2309 if (tb[IFLA_GSO_MAX_SIZE]) { 2310 u32 max_size = nla_get_u32(tb[IFLA_GSO_MAX_SIZE]); 2311 2312 if (max_size > GSO_MAX_SIZE) { 2313 err = -EINVAL; 2314 goto errout; 2315 } 2316 2317 if (dev->gso_max_size ^ max_size) { 2318 netif_set_gso_max_size(dev, max_size); 2319 status |= DO_SETLINK_MODIFIED; 2320 } 2321 } 2322 2323 if (tb[IFLA_GSO_MAX_SEGS]) { 2324 u32 max_segs = nla_get_u32(tb[IFLA_GSO_MAX_SEGS]); 2325 2326 if (max_segs > GSO_MAX_SEGS) { 2327 err = -EINVAL; 2328 goto errout; 2329 } 2330 2331 if (dev->gso_max_segs ^ max_segs) { 2332 dev->gso_max_segs = max_segs; 2333 status |= DO_SETLINK_MODIFIED; 2334 } 2335 } 2336 |
|
2222 if (tb[IFLA_OPERSTATE]) 2223 set_operstate(dev, nla_get_u8(tb[IFLA_OPERSTATE])); 2224 2225 if (tb[IFLA_LINKMODE]) { 2226 unsigned char value = nla_get_u8(tb[IFLA_LINKMODE]); 2227 2228 write_lock_bh(&dev_base_lock); 2229 if (dev->link_mode ^ value) --- 348 unchanged lines hidden (view full) --- 2578 if (tb[IFLA_TXQLEN]) 2579 dev->tx_queue_len = nla_get_u32(tb[IFLA_TXQLEN]); 2580 if (tb[IFLA_OPERSTATE]) 2581 set_operstate(dev, nla_get_u8(tb[IFLA_OPERSTATE])); 2582 if (tb[IFLA_LINKMODE]) 2583 dev->link_mode = nla_get_u8(tb[IFLA_LINKMODE]); 2584 if (tb[IFLA_GROUP]) 2585 dev_set_group(dev, nla_get_u32(tb[IFLA_GROUP])); | 2337 if (tb[IFLA_OPERSTATE]) 2338 set_operstate(dev, nla_get_u8(tb[IFLA_OPERSTATE])); 2339 2340 if (tb[IFLA_LINKMODE]) { 2341 unsigned char value = nla_get_u8(tb[IFLA_LINKMODE]); 2342 2343 write_lock_bh(&dev_base_lock); 2344 if (dev->link_mode ^ value) --- 348 unchanged lines hidden (view full) --- 2693 if (tb[IFLA_TXQLEN]) 2694 dev->tx_queue_len = nla_get_u32(tb[IFLA_TXQLEN]); 2695 if (tb[IFLA_OPERSTATE]) 2696 set_operstate(dev, nla_get_u8(tb[IFLA_OPERSTATE])); 2697 if (tb[IFLA_LINKMODE]) 2698 dev->link_mode = nla_get_u8(tb[IFLA_LINKMODE]); 2699 if (tb[IFLA_GROUP]) 2700 dev_set_group(dev, nla_get_u32(tb[IFLA_GROUP])); |
2701 if (tb[IFLA_GSO_MAX_SIZE]) 2702 netif_set_gso_max_size(dev, nla_get_u32(tb[IFLA_GSO_MAX_SIZE])); 2703 if (tb[IFLA_GSO_MAX_SEGS]) 2704 dev->gso_max_segs = nla_get_u32(tb[IFLA_GSO_MAX_SEGS]); |
|
2586 2587 return dev; 2588} 2589EXPORT_SYMBOL(rtnl_create_link); 2590 2591static int rtnl_group_changelink(const struct sk_buff *skb, 2592 struct net *net, int group, 2593 struct ifinfomsg *ifm, --- 374 unchanged lines hidden (view full) --- 2968{ 2969 int idx; 2970 int s_idx = cb->family; 2971 2972 if (s_idx == 0) 2973 s_idx = 1; 2974 2975 for (idx = 1; idx <= RTNL_FAMILY_MAX; idx++) { | 2705 2706 return dev; 2707} 2708EXPORT_SYMBOL(rtnl_create_link); 2709 2710static int rtnl_group_changelink(const struct sk_buff *skb, 2711 struct net *net, int group, 2712 struct ifinfomsg *ifm, --- 374 unchanged lines hidden (view full) --- 3087{ 3088 int idx; 3089 int s_idx = cb->family; 3090 3091 if (s_idx == 0) 3092 s_idx = 1; 3093 3094 for (idx = 1; idx <= RTNL_FAMILY_MAX; idx++) { |
3095 struct rtnl_link **tab; |
|
2976 int type = cb->nlh->nlmsg_type-RTM_BASE; | 3096 int type = cb->nlh->nlmsg_type-RTM_BASE; |
2977 struct rtnl_link *handlers; | 3097 struct rtnl_link *link; |
2978 rtnl_dumpit_func dumpit; 2979 2980 if (idx < s_idx || idx == PF_PACKET) 2981 continue; 2982 | 3098 rtnl_dumpit_func dumpit; 3099 3100 if (idx < s_idx || idx == PF_PACKET) 3101 continue; 3102 |
2983 handlers = rtnl_dereference(rtnl_msg_handlers[idx]); 2984 if (!handlers) | 3103 if (type < 0 || type >= RTM_NR_MSGTYPES) |
2985 continue; 2986 | 3104 continue; 3105 |
2987 dumpit = READ_ONCE(handlers[type].dumpit); | 3106 tab = rcu_dereference_rtnl(rtnl_msg_handlers[idx]); 3107 if (!tab) 3108 continue; 3109 3110 link = tab[type]; 3111 if (!link) 3112 continue; 3113 3114 dumpit = link->dumpit; |
2988 if (!dumpit) 2989 continue; 2990 2991 if (idx > s_idx) { 2992 memset(&cb->args[0], 0, sizeof(cb->args)); 2993 cb->prev_seq = 0; 2994 cb->seq = 0; 2995 } --- 1313 unchanged lines hidden (view full) --- 4309} 4310 4311/* Process one rtnetlink message. */ 4312 4313static int rtnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, 4314 struct netlink_ext_ack *extack) 4315{ 4316 struct net *net = sock_net(skb->sk); | 3115 if (!dumpit) 3116 continue; 3117 3118 if (idx > s_idx) { 3119 memset(&cb->args[0], 0, sizeof(cb->args)); 3120 cb->prev_seq = 0; 3121 cb->seq = 0; 3122 } --- 1313 unchanged lines hidden (view full) --- 4436} 4437 4438/* Process one rtnetlink message. */ 4439 4440static int rtnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, 4441 struct netlink_ext_ack *extack) 4442{ 4443 struct net *net = sock_net(skb->sk); |
4317 struct rtnl_link *handlers; | 4444 struct rtnl_link *link; 4445 struct module *owner; |
4318 int err = -EOPNOTSUPP; 4319 rtnl_doit_func doit; 4320 unsigned int flags; 4321 int kind; 4322 int family; 4323 int type; 4324 4325 type = nlh->nlmsg_type; --- 7 unchanged lines hidden (view full) --- 4333 return 0; 4334 4335 family = ((struct rtgenmsg *)nlmsg_data(nlh))->rtgen_family; 4336 kind = type&3; 4337 4338 if (kind != 2 && !netlink_net_capable(skb, CAP_NET_ADMIN)) 4339 return -EPERM; 4340 | 4446 int err = -EOPNOTSUPP; 4447 rtnl_doit_func doit; 4448 unsigned int flags; 4449 int kind; 4450 int family; 4451 int type; 4452 4453 type = nlh->nlmsg_type; --- 7 unchanged lines hidden (view full) --- 4461 return 0; 4462 4463 family = ((struct rtgenmsg *)nlmsg_data(nlh))->rtgen_family; 4464 kind = type&3; 4465 4466 if (kind != 2 && !netlink_net_capable(skb, CAP_NET_ADMIN)) 4467 return -EPERM; 4468 |
4341 if (family >= ARRAY_SIZE(rtnl_msg_handlers)) 4342 family = PF_UNSPEC; 4343 | |
4344 rcu_read_lock(); | 4469 rcu_read_lock(); |
4345 handlers = rcu_dereference(rtnl_msg_handlers[family]); 4346 if (!handlers) { 4347 family = PF_UNSPEC; 4348 handlers = rcu_dereference(rtnl_msg_handlers[family]); 4349 } 4350 | |
4351 if (kind == 2 && nlh->nlmsg_flags&NLM_F_DUMP) { 4352 struct sock *rtnl; 4353 rtnl_dumpit_func dumpit; 4354 u16 min_dump_alloc = 0; 4355 | 4470 if (kind == 2 && nlh->nlmsg_flags&NLM_F_DUMP) { 4471 struct sock *rtnl; 4472 rtnl_dumpit_func dumpit; 4473 u16 min_dump_alloc = 0; 4474 |
4356 dumpit = READ_ONCE(handlers[type].dumpit); 4357 if (!dumpit) { | 4475 link = rtnl_get_link(family, type); 4476 if (!link || !link->dumpit) { |
4358 family = PF_UNSPEC; | 4477 family = PF_UNSPEC; |
4359 handlers = rcu_dereference(rtnl_msg_handlers[PF_UNSPEC]); 4360 if (!handlers) | 4478 link = rtnl_get_link(family, type); 4479 if (!link || !link->dumpit) |
4361 goto err_unlock; | 4480 goto err_unlock; |
4362 4363 dumpit = READ_ONCE(handlers[type].dumpit); 4364 if (!dumpit) 4365 goto err_unlock; | |
4366 } | 4481 } |
4482 owner = link->owner; 4483 dumpit = link->dumpit; |
|
4367 | 4484 |
4368 refcount_inc(&rtnl_msg_handlers_ref[family]); 4369 | |
4370 if (type == RTM_GETLINK - RTM_BASE) 4371 min_dump_alloc = rtnl_calcit(skb, nlh); 4372 | 4485 if (type == RTM_GETLINK - RTM_BASE) 4486 min_dump_alloc = rtnl_calcit(skb, nlh); 4487 |
4488 err = 0; 4489 /* need to do this before rcu_read_unlock() */ 4490 if (!try_module_get(owner)) 4491 err = -EPROTONOSUPPORT; 4492 |
|
4373 rcu_read_unlock(); 4374 4375 rtnl = net->rtnl; | 4493 rcu_read_unlock(); 4494 4495 rtnl = net->rtnl; |
4376 { | 4496 if (err == 0) { |
4377 struct netlink_dump_control c = { 4378 .dump = dumpit, 4379 .min_dump_alloc = min_dump_alloc, | 4497 struct netlink_dump_control c = { 4498 .dump = dumpit, 4499 .min_dump_alloc = min_dump_alloc, |
4500 .module = owner, |
|
4380 }; 4381 err = netlink_dump_start(rtnl, skb, nlh, &c); | 4501 }; 4502 err = netlink_dump_start(rtnl, skb, nlh, &c); |
4503 /* netlink_dump_start() will keep a reference on 4504 * module if dump is still in progress. 4505 */ 4506 module_put(owner); |
|
4382 } | 4507 } |
4383 refcount_dec(&rtnl_msg_handlers_ref[family]); | |
4384 return err; 4385 } 4386 | 4508 return err; 4509 } 4510 |
4387 doit = READ_ONCE(handlers[type].doit); 4388 if (!doit) { | 4511 link = rtnl_get_link(family, type); 4512 if (!link || !link->doit) { |
4389 family = PF_UNSPEC; | 4513 family = PF_UNSPEC; |
4390 handlers = rcu_dereference(rtnl_msg_handlers[family]); | 4514 link = rtnl_get_link(PF_UNSPEC, type); 4515 if (!link || !link->doit) 4516 goto out_unlock; |
4391 } 4392 | 4517 } 4518 |
4393 flags = READ_ONCE(handlers[type].flags); | 4519 owner = link->owner; 4520 if (!try_module_get(owner)) { 4521 err = -EPROTONOSUPPORT; 4522 goto out_unlock; 4523 } 4524 4525 flags = link->flags; |
4394 if (flags & RTNL_FLAG_DOIT_UNLOCKED) { | 4526 if (flags & RTNL_FLAG_DOIT_UNLOCKED) { |
4395 refcount_inc(&rtnl_msg_handlers_ref[family]); 4396 doit = READ_ONCE(handlers[type].doit); | 4527 doit = link->doit; |
4397 rcu_read_unlock(); 4398 if (doit) 4399 err = doit(skb, nlh, extack); | 4528 rcu_read_unlock(); 4529 if (doit) 4530 err = doit(skb, nlh, extack); |
4400 refcount_dec(&rtnl_msg_handlers_ref[family]); | 4531 module_put(owner); |
4401 return err; 4402 } | 4532 return err; 4533 } |
4403 | |
4404 rcu_read_unlock(); 4405 4406 rtnl_lock(); | 4534 rcu_read_unlock(); 4535 4536 rtnl_lock(); |
4407 handlers = rtnl_dereference(rtnl_msg_handlers[family]); 4408 if (handlers) { 4409 doit = READ_ONCE(handlers[type].doit); 4410 if (doit) 4411 err = doit(skb, nlh, extack); 4412 } | 4537 link = rtnl_get_link(family, type); 4538 if (link && link->doit) 4539 err = link->doit(skb, nlh, extack); |
4413 rtnl_unlock(); | 4540 rtnl_unlock(); |
4541 4542 module_put(owner); 4543 |
|
4414 return err; 4415 | 4544 return err; 4545 |
4546out_unlock: 4547 rcu_read_unlock(); 4548 return err; 4549 |
|
4416err_unlock: 4417 rcu_read_unlock(); 4418 return -EOPNOTSUPP; 4419} 4420 4421static void rtnetlink_rcv(struct sk_buff *skb) 4422{ 4423 netlink_rcv_skb(skb, &rtnetlink_rcv_msg); --- 69 unchanged lines hidden (view full) --- 4493 4494static struct pernet_operations rtnetlink_net_ops = { 4495 .init = rtnetlink_net_init, 4496 .exit = rtnetlink_net_exit, 4497}; 4498 4499void __init rtnetlink_init(void) 4500{ | 4550err_unlock: 4551 rcu_read_unlock(); 4552 return -EOPNOTSUPP; 4553} 4554 4555static void rtnetlink_rcv(struct sk_buff *skb) 4556{ 4557 netlink_rcv_skb(skb, &rtnetlink_rcv_msg); --- 69 unchanged lines hidden (view full) --- 4627 4628static struct pernet_operations rtnetlink_net_ops = { 4629 .init = rtnetlink_net_init, 4630 .exit = rtnetlink_net_exit, 4631}; 4632 4633void __init rtnetlink_init(void) 4634{ |
4501 int i; 4502 4503 for (i = 0; i < ARRAY_SIZE(rtnl_msg_handlers_ref); i++) 4504 refcount_set(&rtnl_msg_handlers_ref[i], 1); 4505 | |
4506 if (register_pernet_subsys(&rtnetlink_net_ops)) 4507 panic("rtnetlink_init: cannot initialize rtnetlink\n"); 4508 4509 register_netdevice_notifier(&rtnetlink_dev_notifier); 4510 4511 rtnl_register(PF_UNSPEC, RTM_GETLINK, rtnl_getlink, 4512 rtnl_dump_ifinfo, 0); 4513 rtnl_register(PF_UNSPEC, RTM_SETLINK, rtnl_setlink, NULL, 0); --- 18 unchanged lines hidden --- | 4635 if (register_pernet_subsys(&rtnetlink_net_ops)) 4636 panic("rtnetlink_init: cannot initialize rtnetlink\n"); 4637 4638 register_netdevice_notifier(&rtnetlink_dev_notifier); 4639 4640 rtnl_register(PF_UNSPEC, RTM_GETLINK, rtnl_getlink, 4641 rtnl_dump_ifinfo, 0); 4642 rtnl_register(PF_UNSPEC, RTM_SETLINK, rtnl_setlink, NULL, 0); --- 18 unchanged lines hidden --- |