cregit-Linux how code gets into the kernel

Release 4.11 net/core/rtnetlink.c

Directory: net/core
/*
 * INET         An implementation of the TCP/IP protocol suite for the LINUX
 *              operating system.  INET is implemented using the  BSD Socket
 *              interface as the means of communication with the user level.
 *
 *              Routing netlink socket interface: protocol independent part.
 *
 * Authors:     Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
 *
 *              This program is free software; you can redistribute it and/or
 *              modify it under the terms of the GNU General Public License
 *              as published by the Free Software Foundation; either version
 *              2 of the License, or (at your option) any later version.
 *
 *      Fixes:
 *      Vitaly E. Lavrov                RTA_OK arithmetics was wrong.
 */

#include <linux/errno.h>
#include <linux/module.h>
#include <linux/types.h>
#include <linux/socket.h>
#include <linux/kernel.h>
#include <linux/timer.h>
#include <linux/string.h>
#include <linux/sockios.h>
#include <linux/net.h>
#include <linux/fcntl.h>
#include <linux/mm.h>
#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/capability.h>
#include <linux/skbuff.h>
#include <linux/init.h>
#include <linux/security.h>
#include <linux/mutex.h>
#include <linux/if_addr.h>
#include <linux/if_bridge.h>
#include <linux/if_vlan.h>
#include <linux/pci.h>
#include <linux/etherdevice.h>

#include <linux/uaccess.h>

#include <linux/inet.h>
#include <linux/netdevice.h>
#include <net/switchdev.h>
#include <net/ip.h>
#include <net/protocol.h>
#include <net/arp.h>
#include <net/route.h>
#include <net/udp.h>
#include <net/tcp.h>
#include <net/sock.h>
#include <net/pkt_sched.h>
#include <net/fib_rules.h>
#include <net/rtnetlink.h>
#include <net/net_namespace.h>


struct rtnl_link {
	
rtnl_doit_func		doit;
	
rtnl_dumpit_func	dumpit;
	
rtnl_calcit_func 	calcit;
};

static DEFINE_MUTEX(rtnl_mutex);


void rtnl_lock(void) { mutex_lock(&rtnl_mutex); }

Contributors

PersonTokensPropCommitsCommitProp
Linus Torvalds (pre-git)538.46%133.33%
Stephen Hemminger538.46%133.33%
Linus Torvalds323.08%133.33%
Total13100.00%3100.00%

EXPORT_SYMBOL(rtnl_lock); static struct sk_buff *defer_kfree_skb_list;
void rtnl_kfree_skbs(struct sk_buff *head, struct sk_buff *tail) { if (head && tail) { tail->next = defer_kfree_skb_list; defer_kfree_skb_list = head; } }

Contributors

PersonTokensPropCommitsCommitProp
Eric Dumazet33100.00%1100.00%
Total33100.00%1100.00%

EXPORT_SYMBOL(rtnl_kfree_skbs);
void __rtnl_unlock(void) { struct sk_buff *head = defer_kfree_skb_list; defer_kfree_skb_list = NULL; mutex_unlock(&rtnl_mutex); while (head) { struct sk_buff *next = head->next; kfree_skb(head); cond_resched(); head = next; } }

Contributors

PersonTokensPropCommitsCommitProp
Eric Dumazet3874.51%133.33%
Christoph Hellwig815.69%133.33%
Stephen Hemminger59.80%133.33%
Total51100.00%3100.00%


void rtnl_unlock(void) { /* This fellow will unlock it for us. */ netdev_run_todo(); }

Contributors

PersonTokensPropCommitsCommitProp
Linus Torvalds (pre-git)763.64%240.00%
David S. Miller327.27%240.00%
Herbert Xu19.09%120.00%
Total11100.00%5100.00%

EXPORT_SYMBOL(rtnl_unlock);
int rtnl_trylock(void) { return mutex_trylock(&rtnl_mutex); }

Contributors

PersonTokensPropCommitsCommitProp
Stephen Hemminger14100.00%1100.00%
Total14100.00%1100.00%

EXPORT_SYMBOL(rtnl_trylock);
int rtnl_is_locked(void) { return mutex_is_locked(&rtnl_mutex); }

Contributors

PersonTokensPropCommitsCommitProp
Patrick McHardy14100.00%1100.00%
Total14100.00%1100.00%

EXPORT_SYMBOL(rtnl_is_locked); #ifdef CONFIG_PROVE_LOCKING
bool lockdep_rtnl_is_held(void) { return lockdep_is_held(&rtnl_mutex); }

Contributors

PersonTokensPropCommitsCommitProp
Paul E. McKenney1392.86%150.00%
Yaowei Bai17.14%150.00%
Total14100.00%2100.00%

EXPORT_SYMBOL(lockdep_rtnl_is_held); #endif /* #ifdef CONFIG_PROVE_LOCKING */ static struct rtnl_link *rtnl_msg_handlers[RTNL_FAMILY_MAX + 1];
static inline int rtm_msgindex(int msgtype) { int msgindex = msgtype - RTM_BASE; /* * msgindex < 0 implies someone tried to register a netlink * control code. msgindex >= RTM_NR_MSGTYPES may indicate that * the message type has not been added to linux/rtnetlink.h */ BUG_ON(msgindex < 0 || msgindex >= RTM_NR_MSGTYPES); return msgindex; }

Contributors

PersonTokensPropCommitsCommitProp
Thomas Graf32100.00%1100.00%
Total32100.00%1100.00%


static rtnl_doit_func rtnl_get_doit(int protocol, int msgindex) { struct rtnl_link *tab; if (protocol <= RTNL_FAMILY_MAX) tab = rtnl_msg_handlers[protocol]; else tab = NULL; if (tab == NULL || tab[msgindex].doit == NULL) tab = rtnl_msg_handlers[PF_UNSPEC]; return tab[msgindex].doit; }

Contributors

PersonTokensPropCommitsCommitProp
Thomas Graf5483.08%250.00%
Patrick McHardy1116.92%250.00%
Total65100.00%4100.00%


static rtnl_dumpit_func rtnl_get_dumpit(int protocol, int msgindex) { struct rtnl_link *tab; if (protocol <= RTNL_FAMILY_MAX) tab = rtnl_msg_handlers[protocol]; else tab = NULL; if (tab == NULL || tab[msgindex].dumpit == NULL) tab = rtnl_msg_handlers[PF_UNSPEC]; return tab[msgindex].dumpit; }

Contributors

PersonTokensPropCommitsCommitProp
Thomas Graf5483.08%250.00%
Patrick McHardy1116.92%250.00%
Total65100.00%4100.00%


static rtnl_calcit_func rtnl_get_calcit(int protocol, int msgindex) { struct rtnl_link *tab; if (protocol <= RTNL_FAMILY_MAX) tab = rtnl_msg_handlers[protocol]; else tab = NULL; if (tab == NULL || tab[msgindex].calcit == NULL) tab = rtnl_msg_handlers[PF_UNSPEC]; return tab[msgindex].calcit; }

Contributors

PersonTokensPropCommitsCommitProp
Greg Rose65100.00%1100.00%
Total65100.00%1100.00%

/** * __rtnl_register - Register a rtnetlink message type * @protocol: Protocol family or PF_UNSPEC * @msgtype: rtnetlink message type * @doit: Function pointer called for each request message * @dumpit: Function pointer called for each dump request (NLM_F_DUMP) message * @calcit: Function pointer to calc size of dump message * * Registers the specified function pointers (at least one of them has * to be non-NULL) to be called whenever a request message for the * specified protocol family and message type is received. * * The special protocol family PF_UNSPEC may be used to define fallback * function pointers for the case when no entry for the specific protocol * family exists. * * Returns 0 on success or a negative error code. */
int __rtnl_register(int protocol, int msgtype, rtnl_doit_func doit, rtnl_dumpit_func dumpit, rtnl_calcit_func calcit) { struct rtnl_link *tab; int msgindex; BUG_ON(protocol < 0 || protocol > RTNL_FAMILY_MAX); msgindex = rtm_msgindex(msgtype); tab = rtnl_msg_handlers[protocol]; if (tab == NULL) { tab = kcalloc(RTM_NR_MSGTYPES, sizeof(*tab), GFP_KERNEL); if (tab == NULL) return -ENOBUFS; rtnl_msg_handlers[protocol] = tab; } if (doit) tab[msgindex].doit = doit; if (dumpit) tab[msgindex].dumpit = dumpit; if (calcit) tab[msgindex].calcit = calcit; return 0; }

Contributors

PersonTokensPropCommitsCommitProp
Thomas Graf11786.67%133.33%
Greg Rose1611.85%133.33%
Patrick McHardy21.48%133.33%
Total135100.00%3100.00%

EXPORT_SYMBOL_GPL(__rtnl_register); /** * rtnl_register - Register a rtnetlink message type * * Identical to __rtnl_register() but panics on failure. This is useful * as failure of this function is very unlikely, it can only happen due * to lack of memory when allocating the chain to store all message * handlers for a protocol. Meant for use in init functions where lack * of memory implies no sense in continuing. */
void rtnl_register(int protocol, int msgtype, rtnl_doit_func doit, rtnl_dumpit_func dumpit, rtnl_calcit_func calcit) { if (__rtnl_register(protocol, msgtype, doit, dumpit, calcit) < 0) panic("Unable to register rtnetlink message handler, " "protocol = %d, message type = %d\n", protocol, msgtype); }

Contributors

PersonTokensPropCommitsCommitProp
Thomas Graf4289.36%150.00%
Greg Rose510.64%150.00%
Total47100.00%2100.00%

EXPORT_SYMBOL_GPL(rtnl_register); /** * rtnl_unregister - Unregister a rtnetlink message type * @protocol: Protocol family or PF_UNSPEC * @msgtype: rtnetlink message type * * Returns 0 on success or a negative error code. */
int rtnl_unregister(int protocol, int msgtype) { int msgindex; BUG_ON(protocol < 0 || protocol > RTNL_FAMILY_MAX); msgindex = rtm_msgindex(msgtype); if (rtnl_msg_handlers[protocol] == NULL) return -ENOENT; rtnl_msg_handlers[protocol][msgindex].doit = NULL; rtnl_msg_handlers[protocol][msgindex].dumpit = NULL; rtnl_msg_handlers[protocol][msgindex].calcit = NULL; return 0; }

Contributors

PersonTokensPropCommitsCommitProp
Thomas Graf7083.33%133.33%
Mathias Krause1214.29%133.33%
Patrick McHardy22.38%133.33%
Total84100.00%3100.00%

EXPORT_SYMBOL_GPL(rtnl_unregister); /** * rtnl_unregister_all - Unregister all rtnetlink message type of a protocol * @protocol : Protocol family or PF_UNSPEC * * Identical to calling rtnl_unregster() for all registered message types * of a certain protocol family. */
void rtnl_unregister_all(int protocol) { BUG_ON(protocol < 0 || protocol > RTNL_FAMILY_MAX); kfree(rtnl_msg_handlers[protocol]); rtnl_msg_handlers[protocol] = NULL; }

Contributors

PersonTokensPropCommitsCommitProp
Thomas Graf3294.12%150.00%
Patrick McHardy25.88%150.00%
Total34100.00%2100.00%

EXPORT_SYMBOL_GPL(rtnl_unregister_all); static LIST_HEAD(link_ops);
static const struct rtnl_link_ops *rtnl_link_ops_get(const char *kind) { const struct rtnl_link_ops *ops; list_for_each_entry(ops, &link_ops, list) { if (!strcmp(ops->kind, kind)) return ops; } return NULL; }

Contributors

PersonTokensPropCommitsCommitProp
Eric Dumazet48100.00%1100.00%
Total48100.00%1100.00%

/** * __rtnl_link_register - Register rtnl_link_ops with rtnetlink. * @ops: struct rtnl_link_ops * to register * * The caller must hold the rtnl_mutex. This function should be used * by drivers that create devices during module initialization. It * must be called before registering the devices. * * Returns 0 on success or a negative error code. */
int __rtnl_link_register(struct rtnl_link_ops *ops) { if (rtnl_link_ops_get(ops->kind)) return -EEXIST; /* The check for setup is here because if ops * does not have that filled up, it is not possible * to use the ops for creating device. So do not * fill up dellink as well. That disables rtnl_dellink. */ if (ops->setup && !ops->dellink) ops->dellink = unregister_netdevice_queue; list_add_tail(&ops->list, &link_ops); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
Patrick McHardy3461.82%233.33%
Eric Dumazet1425.45%233.33%
Jiri Pirko59.09%116.67%
Linus Torvalds (pre-git)23.64%116.67%
Total55100.00%6100.00%

EXPORT_SYMBOL_GPL(__rtnl_link_register); /** * rtnl_link_register - Register rtnl_link_ops with rtnetlink. * @ops: struct rtnl_link_ops * to register * * Returns 0 on success or a negative error code. */
int rtnl_link_register(struct rtnl_link_ops *ops) { int err; rtnl_lock(); err = __rtnl_link_register(ops); rtnl_unlock(); return err; }

Contributors

PersonTokensPropCommitsCommitProp
Patrick McHardy2793.10%133.33%
Thomas Graf13.45%133.33%
Linus Torvalds (pre-git)13.45%133.33%
Total29100.00%3100.00%

EXPORT_SYMBOL_GPL(rtnl_link_register);
static void __rtnl_kill_links(struct net *net, struct rtnl_link_ops *ops) { struct net_device *dev; LIST_HEAD(list_kill); for_each_netdev(net, dev) { if (dev->rtnl_link_ops == ops) ops->dellink(dev, &list_kill); } unregister_netdevice_many(&list_kill); }

Contributors

PersonTokensPropCommitsCommitProp
Patrick McHardy3356.90%233.33%
Eric Dumazet1424.14%116.67%
Pavel Emelyanov813.79%233.33%
Eric W. Biedermann35.17%116.67%
Total58100.00%6100.00%

/** * __rtnl_link_unregister - Unregister rtnl_link_ops from rtnetlink. * @ops: struct rtnl_link_ops * to unregister * * The caller must hold the rtnl_mutex. */
void __rtnl_link_unregister(struct rtnl_link_ops *ops) { struct net *net; for_each_net(net) { __rtnl_kill_links(net, ops); } list_del(&ops->list); }

Contributors

PersonTokensPropCommitsCommitProp
Pavel Emelyanov2775.00%133.33%
Patrick McHardy822.22%133.33%
Linus Torvalds (pre-git)12.78%133.33%
Total36100.00%3100.00%

EXPORT_SYMBOL_GPL(__rtnl_link_unregister); /* Return with the rtnl_lock held when there are no network * devices unregistering in any network namespace. */
static void rtnl_lock_unregistering_all(void) { struct net *net; bool unregistering; DEFINE_WAIT_FUNC(wait, woken_wake_function); add_wait_queue(&netdev_unregistering_wq, &wait); for (;;) { unregistering = false; rtnl_lock(); for_each_net(net) { if (net->dev_unreg_count > 0) { unregistering = true; break; } } if (!unregistering) break; __rtnl_unlock(); wait_woken(&wait, TASK_UNINTERRUPTIBLE, MAX_SCHEDULE_TIMEOUT); } remove_wait_queue(&netdev_unregistering_wq, &wait); }

Contributors

PersonTokensPropCommitsCommitProp
Cong Wang7578.95%150.00%
Peter Zijlstra2021.05%150.00%
Total95100.00%2100.00%

/** * rtnl_link_unregister - Unregister rtnl_link_ops from rtnetlink. * @ops: struct rtnl_link_ops * to unregister */
void rtnl_link_unregister(struct rtnl_link_ops *ops) { /* Close the race with cleanup_net() */ mutex_lock(&net_mutex); rtnl_lock_unregistering_all(); __rtnl_link_unregister(ops); rtnl_unlock(); mutex_unlock(&net_mutex); }

Contributors

PersonTokensPropCommitsCommitProp
Patrick McHardy1955.88%133.33%
Cong Wang1441.18%133.33%
Linus Torvalds (pre-git)12.94%133.33%
Total34100.00%3100.00%

EXPORT_SYMBOL_GPL(rtnl_link_unregister);
static size_t rtnl_link_get_slave_info_data_size(const struct net_device *dev) { struct net_device *master_dev; const struct rtnl_link_ops *ops; master_dev = netdev_master_upper_dev_get((struct net_device *) dev); if (!master_dev) return 0; ops = master_dev->rtnl_link_ops; if (!ops || !ops->get_slave_size) return 0; /* IFLA_INFO_SLAVE_DATA + nested data */ return nla_total_size(sizeof(struct nlattr)) + ops->get_slave_size(master_dev, dev); }

Contributors

PersonTokensPropCommitsCommitProp
Jiri Pirko7996.34%150.00%
Fernando Luis Vázquez Cao33.66%150.00%
Total82100.00%2100.00%


static size_t rtnl_link_get_size(const struct net_device *dev) { const struct rtnl_link_ops *ops = dev->rtnl_link_ops; size_t size; if (!ops) return 0; size = nla_total_size(sizeof(struct nlattr)) + /* IFLA_LINKINFO */ nla_total_size(strlen(ops->kind) + 1); /* IFLA_INFO_KIND */ if (ops->get_size) /* IFLA_INFO_DATA + nested data */ size += nla_total_size(sizeof(struct nlattr)) + ops->get_size(dev); if (ops->get_xstats_size) /* IFLA_INFO_XSTATS */ size += nla_total_size(ops->get_xstats_size(dev)); size += rtnl_link_get_slave_info_data_size(dev); return size; }

Contributors

PersonTokensPropCommitsCommitProp
Patrick McHardy8172.32%120.00%
Thomas Graf1210.71%240.00%
Linus Torvalds (pre-git)1210.71%120.00%
Jiri Pirko76.25%120.00%
Total112100.00%5100.00%

static LIST_HEAD(rtnl_af_ops);
static const struct rtnl_af_ops *rtnl_af_lookup(const int family) { const struct rtnl_af_ops *ops; list_for_each_entry(ops, &rtnl_af_ops, list) { if (ops->family == family) return ops; } return NULL; }

Contributors

PersonTokensPropCommitsCommitProp
Thomas Graf43100.00%1100.00%
Total43100.00%1100.00%

/** * rtnl_af_register - Register rtnl_af_ops with rtnetlink. * @ops: struct rtnl_af_ops * to register * * Returns 0 on success or a negative error code. */
void rtnl_af_register(struct rtnl_af_ops *ops) { rtnl_lock(); list_add_tail(&ops->list, &rtnl_af_ops); rtnl_unlock(); }

Contributors

PersonTokensPropCommitsCommitProp
Thomas Graf2281.48%150.00%
Stephen Hemminger518.52%150.00%
Total27100.00%2100.00%

EXPORT_SYMBOL_GPL(rtnl_af_register); /** * __rtnl_af_unregister - Unregister rtnl_af_ops from rtnetlink. * @ops: struct rtnl_af_ops * to unregister * * The caller must hold the rtnl_mutex. */
void __rtnl_af_unregister(struct rtnl_af_ops *ops) { list_del(&ops->list); }

Contributors

PersonTokensPropCommitsCommitProp
Thomas Graf18100.00%1100.00%
Total18100.00%1100.00%

EXPORT_SYMBOL_GPL(__rtnl_af_unregister); /** * rtnl_af_unregister - Unregister rtnl_af_ops from rtnetlink. * @ops: struct rtnl_af_ops * to unregister */
void rtnl_af_unregister(struct rtnl_af_ops *ops) { rtnl_lock(); __rtnl_af_unregister(ops); rtnl_unlock(); }

Contributors

PersonTokensPropCommitsCommitProp
Thomas Graf21100.00%1100.00%
Total21100.00%1100.00%

EXPORT_SYMBOL_GPL(rtnl_af_unregister);
static size_t rtnl_link_get_af_size(const struct net_device *dev, u32 ext_filter_mask) { struct rtnl_af_ops *af_ops; size_t size; /* IFLA_AF_SPEC */ size = nla_total_size(sizeof(struct nlattr)); list_for_each_entry(af_ops, &rtnl_af_ops, list) { if (af_ops->get_link_af_size) { /* AF_* + nested data */ size += nla_total_size(sizeof(struct nlattr)) + af_ops->get_link_af_size(dev, ext_filter_mask); } } return size; }

Contributors

PersonTokensPropCommitsCommitProp
Thomas Graf7293.51%150.00%
Arad, Ronen56.49%150.00%
Total77100.00%2100.00%


static bool rtnl_have_link_slave_info(const struct net_device *dev) { struct net_device *master_dev; master_dev = netdev_master_upper_dev_get((struct net_device *) dev); if (master_dev && master_dev->rtnl_link_ops) return true; return false; }

Contributors

PersonTokensPropCommitsCommitProp
Jiri Pirko43100.00%1100.00%
Total43100.00%1100.00%


static int rtnl_link_slave_info_fill(struct sk_buff *skb, const struct net_device *dev) { struct net_device *master_dev; const struct rtnl_link_ops *ops; struct nlattr *slave_data; int err; master_dev = netdev_master_upper_dev_get((struct net_device *) dev); if (!master_dev) return 0; ops = master_dev->rtnl_link_ops; if (!ops) return 0; if (nla_put_string(skb, IFLA_INFO_SLAVE_KIND, ops->kind) < 0) return -EMSGSIZE; if (ops->fill_slave_info) { slave_data = nla_nest_start(skb, IFLA_INFO_SLAVE_DATA); if (!slave_data) return -EMSGSIZE; err = ops->fill_slave_info(skb, master_dev, dev); if (err < 0) goto err_cancel_slave_data; nla_nest_end(skb, slave_data); } return 0; err_cancel_slave_data: nla_nest_cancel(skb, slave_data); return err; }

Contributors

PersonTokensPropCommitsCommitProp
Jiri Pirko11874.21%125.00%
Patrick McHardy3924.53%125.00%
Linus Torvalds (pre-git)10.63%125.00%
Thomas Graf10.63%125.00%
Total159100.00%4100.00%


static int rtnl_link_info_fill(struct sk_buff *skb, const struct net_device *dev) { const struct rtnl_link_ops *ops = dev->rtnl_link_ops; struct nlattr *data; int err; if (!ops) return 0; if (nla_put_string(skb, IFLA_INFO_KIND, ops->kind) < 0) return -EMSGSIZE; if (ops->fill_xstats) { err = ops->fill_xstats(skb, dev); if (err < 0) return err; } if (ops->fill_info) { data = nla_nest_start(skb, IFLA_INFO_DATA); if (data == NULL) return -EMSGSIZE; err = ops->fill_info(skb, dev); if (err < 0) goto err_cancel_data; nla_nest_end(skb, data); } return 0; err_cancel_data: nla_nest_cancel(skb, data); return err; }

Contributors

PersonTokensPropCommitsCommitProp
Jiri Pirko12981.13%133.33%
Patrick McHardy2918.24%133.33%
Linus Torvalds (pre-git)10.63%133.33%
Total159100.00%3100.00%


static int rtnl_link_fill(struct sk_buff *skb, const struct net_device *dev) { struct nlattr *linkinfo; int err = -EMSGSIZE; linkinfo = nla_nest_start(skb, IFLA_LINKINFO); if (linkinfo == NULL) goto out; err = rtnl_link_info_fill(skb, dev); if (err < 0) goto err_cancel_link; err = rtnl_link_slave_info_fill(skb, dev); if (err < 0) goto err_cancel_link; nla_nest_end(skb, linkinfo); return 0; err_cancel_link: nla_nest_cancel(skb, linkinfo); out: return err; }

Contributors

PersonTokensPropCommitsCommitProp
Patrick McHardy5753.77%125.00%
Jiri Pirko4643.40%125.00%
Linus Torvalds (pre-git)21.89%125.00%
Wei Yongjun10.94%125.00%
Total106100.00%4100.00%


int rtnetlink_send(struct sk_buff *skb, struct net *net, u32 pid, unsigned int group, int echo) { struct sock *rtnl = net->rtnl; int err = 0; NETLINK_CB(skb).dst_group = group; if (echo) atomic_inc(&skb->users); netlink_broadcast(rtnl, skb, pid, group, GFP_KERNEL); if (echo) err = netlink_unicast(rtnl, skb, pid, MSG_DONTWAIT); return err; }

Contributors

PersonTokensPropCommitsCommitProp
Linus Torvalds (pre-git)7782.80%125.00%
Denis V. Lunev1415.05%125.00%
Patrick McHardy11.08%125.00%
Eric Dumazet11.08%125.00%
Total93100.00%4100.00%


int rtnl_unicast(struct sk_buff *skb, struct net *net, u32 pid) { struct sock *rtnl = net->rtnl; return nlmsg_unicast(rtnl, skb, pid); }

Contributors

PersonTokensPropCommitsCommitProp
Thomas Graf2362.16%150.00%
Denis V. Lunev1437.84%150.00%
Total37100.00%2100.00%

EXPORT_SYMBOL(rtnl_unicast);
void rtnl_notify(struct sk_buff *skb, struct net *net, u32 pid, u32 group, struct nlmsghdr *nlh, gfp_t flags) { struct sock *rtnl = net->rtnl; int report = 0; if (nlh) report = nlmsg_report(nlh); nlmsg_notify(rtnl, skb, pid, group, report, flags); }

Contributors

PersonTokensPropCommitsCommitProp
Thomas Graf5376.81%133.33%
Denis V. Lunev1420.29%133.33%
Pablo Neira Ayuso22.90%133.33%
Total69100.00%3100.00%

EXPORT_SYMBOL(rtnl_notify);
void rtnl_set_sk_err(struct net *net, u32 group, int error) { struct sock *rtnl = net->rtnl; netlink_set_err(rtnl, 0, group, error); }

Contributors

PersonTokensPropCommitsCommitProp
Thomas Graf2261.11%150.00%
Denis V. Lunev1438.89%150.00%
Total36100.00%2100.00%

EXPORT_SYMBOL(rtnl_set_sk_err);
int rtnetlink_put_metrics(struct sk_buff *skb, u32 *metrics) { struct nlattr *mx; int i, valid = 0; mx = nla_nest_start(skb, RTA_METRICS); if (mx == NULL) return -ENOBUFS; for (i = 0; i < RTAX_MAX; i++) { if (metrics[i]) { if (i == RTAX_CC_ALGO - 1) { char tmp[TCP_CA_NAME_MAX], *name; name = tcp_ca_get_name_by_key(metrics[i], tmp); if (!name) continue; if (nla_put_string(skb, i + 1, name)) goto nla_put_failure; } else if (i == RTAX_FEATURES - 1) { u32 user_features = metrics[i] & RTAX_FEATURE_MASK; if (!user_features) continue; BUILD_BUG_ON(RTAX_FEATURE_MASK & DST_FEATURE_MASK); if (nla_put_u32(skb, i + 1, user_features)) goto nla_put_failure; } else { if (nla_put_u32(skb, i + 1, metrics[i])) goto nla_put_failure; } valid++; } } if (!valid) { nla_nest_cancel(skb, mx); return 0; } return nla_nest_end(skb, mx); nla_put_failure: nla_nest_cancel(skb, mx); return -EMSGSIZE; }

Contributors

PersonTokensPropCommitsCommitProp
Daniel Borkmann10243.40%222.22%
Linus Torvalds (pre-git)7431.49%111.11%
Thomas Graf3314.04%222.22%
David S. Miller198.09%222.22%
Phil Sutter62.55%111.11%
Alexey Kuznetsov10.43%111.11%
Total235100.00%9100.00%

EXPORT_SYMBOL(rtnetlink_put_metrics);
int rtnl_put_cacheinfo(struct sk_buff *skb, struct dst_entry *dst, u32 id, long expires, u32 error) { struct rta_cacheinfo ci = { .rta_lastuse = jiffies_delta_to_clock_t(jiffies - dst->lastuse), .rta_used = dst->__use, .rta_clntref = atomic_read(&(dst->__refcnt)), .rta_error = error, .rta_id = id, }; if (expires) { unsigned long clock; clock = jiffies_to_clock_t(abs(expires)); clock = min_t(unsigned long, clock, INT_MAX); ci.rta_expires = (expires > 0) ? clock : -clock; } return nla_put(skb, RTA_CACHEINFO, sizeof(ci), &ci); }

Contributors

PersonTokensPropCommitsCommitProp
Thomas Graf9772.39%133.33%
Li Wei3626.87%133.33%
Eric Dumazet10.75%133.33%
Total134100.00%3100.00%

EXPORT_SYMBOL_GPL(rtnl_put_cacheinfo);
static void set_operstate(struct net_device *dev, unsigned char transition) { unsigned char operstate = dev->operstate; switch (transition) { case IF_OPER_UP: if ((operstate == IF_OPER_DORMANT || operstate == IF_OPER_UNKNOWN) && !netif_dormant(dev)) operstate = IF_OPER_UP; break; case IF_OPER_DORMANT: if (operstate == IF_OPER_UP || operstate == IF_OPER_UNKNOWN) operstate = IF_OPER_DORMANT; break; } if (dev->operstate != operstate) { write_lock_bh(&dev_base_lock); dev->operstate = operstate; write_unlock_bh(&dev_base_lock); netdev_state_change(dev); } }

Contributors

PersonTokensPropCommitsCommitProp
Stefan Rompf10599.06%150.00%
David S. Miller10.94%150.00%
Total106100.00%2100.00%


static unsigned int rtnl_dev_get_flags(const struct net_device *dev) { return (dev->flags & ~(IFF_PROMISC | IFF_ALLMULTI)) | (dev->gflags & (IFF_PROMISC | IFF_ALLMULTI)); }

Contributors

PersonTokensPropCommitsCommitProp
Jiri Benc39100.00%1100.00%
Total39100.00%1100.00%


static unsigned int rtnl_dev_combine_flags(const struct net_device *dev, const struct ifinfomsg *ifm) { unsigned int flags = ifm->ifi_flags; /* bugwards compatibility: ifi_change == 0 is treated as ~0 */