cregit-Linux how code gets into the kernel

Release 4.8 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 <asm/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
stephen hemmingerstephen hemminger538.46%133.33%
pre-gitpre-git538.46%133.33%
linus torvaldslinus 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 dumazeteric 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 dumazeteric dumazet3874.51%133.33%
christoph hellwigchristoph hellwig815.69%133.33%
stephen hemmingerstephen hemminger59.80%133.33%
Total51100.00%3100.00%


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

Contributors

PersonTokensPropCommitsCommitProp
pre-gitpre-git763.64%240.00%
david s. millerdavid s. miller327.27%240.00%
herbert xuherbert xu19.09%120.00%
Total11100.00%5100.00%

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

Contributors

PersonTokensPropCommitsCommitProp
stephen hemmingerstephen 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 mchardypatrick 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. mckenneypaul e. mckenney1392.86%150.00%
yaowei baiyaowei 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 grafthomas 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 grafthomas graf5483.08%250.00%
patrick mchardypatrick 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 grafthomas graf5483.08%250.00%
patrick mchardypatrick 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 rosegreg 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 grafthomas graf11786.67%133.33%
greg rosegreg rose1611.85%133.33%
patrick mchardypatrick 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 grafthomas graf4289.36%150.00%
greg rosegreg 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; return 0; }

Contributors

PersonTokensPropCommitsCommitProp
thomas grafthomas graf7097.22%150.00%
patrick mchardypatrick mchardy22.78%150.00%
Total72100.00%2100.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 grafthomas graf3294.12%150.00%
patrick mchardypatrick 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 dumazeteric 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 mchardypatrick mchardy3461.82%233.33%
eric dumazeteric dumazet1425.45%233.33%
jiri pirkojiri pirko59.09%116.67%
pre-gitpre-git23.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 mchardypatrick mchardy2793.10%133.33%
pre-gitpre-git13.45%133.33%
thomas grafthomas graf13.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 mchardypatrick mchardy3356.90%233.33%
eric dumazeteric dumazet1424.14%116.67%
pavel emelianovpavel emelianov813.79%233.33%
eric w. biedermaneric w. biederman35.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 emelianovpavel emelianov2775.00%133.33%
patrick mchardypatrick mchardy822.22%133.33%
pre-gitpre-git12.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 wangcong wang7578.95%150.00%
peter zijlstrapeter 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 mchardypatrick mchardy1955.88%133.33%
cong wangcong wang1441.18%133.33%
pre-gitpre-git12.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 pirkojiri pirko7996.34%150.00%
fernando luis vazquez caofernando luis vazquez 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 mchardypatrick mchardy8172.32%120.00%
pre-gitpre-git1210.71%120.00%
thomas grafthomas graf1210.71%240.00%
jiri pirkojiri 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 grafthomas 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 grafthomas graf2281.48%150.00%
stephen hemmingerstephen 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 grafthomas 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 grafthomas 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 grafthomas graf7293.51%150.00%
ronen aradronen arad56.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 pirkojiri 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 pirkojiri pirko11874.21%125.00%
patrick mchardypatrick mchardy3924.53%125.00%
pre-gitpre-git10.63%125.00%
thomas grafthomas 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 pirkojiri pirko12981.13%133.33%
patrick mchardypatrick mchardy2918.24%133.33%
pre-gitpre-git10.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 mchardypatrick mchardy5753.77%125.00%
jiri pirkojiri pirko4643.40%125.00%
pre-gitpre-git21.89%125.00%
wei yongjunwei 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
pre-gitpre-git7782.80%125.00%
denis v. lunevdenis v. lunev1415.05%125.00%
eric dumazeteric dumazet11.08%125.00%
patrick mchardypatrick mchardy11.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 grafthomas graf2362.16%150.00%
denis v. lunevdenis 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 grafthomas graf5376.81%133.33%
denis v. lunevdenis v. lunev1420.29%133.33%
pablo neira ayusopablo 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 grafthomas graf2261.11%150.00%
denis v. lunevdenis 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; 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 borkmanndaniel borkmann10244.54%225.00%
pre-gitpre-git7432.31%112.50%
thomas grafthomas graf3314.41%225.00%
david s. millerdavid s. miller198.30%225.00%
alexey kuznetsovalexey kuznetsov10.44%112.50%
Total229100.00%8100.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 grafthomas graf9772.39%133.33%
li weili wei3626.87%133.33%
eric dumazeteric 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 rompfstefan rompf10599.06%150.00%
david s. millerdavid 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 bencjiri 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 */ if (ifm->ifi_change) flags = (flags & ifm->ifi_change) | (rtnl_dev_get_flags(dev) & ~ifm->ifi_change); return flags; }

Contributors

PersonTokensPropCommitsCommitProp
patrick mchardypatrick mchardy5694.92%150.00%
jiri bencjiri benc35.08%150.00%
Total59100.00%2100.00%


static void copy_rtnl_link_stats(struct rtnl_link_stats *a, const struct rtnl_link_stats64 *b) { a->rx_packets = b->rx_packets; a->tx_packets = b->tx_packets; a->rx_bytes = b->rx_bytes; a->tx_bytes = b->tx_bytes; a->rx_errors = b->rx_errors; a->tx_errors = b->tx_errors; a->rx_dropped = b->rx_dropped; a->tx_dropped = b->tx_dropped; a->multicast = b->multicast; a->collisions = b->collisions; a->rx_length_errors = b->rx_length_errors; a->rx_over_errors = b->rx_over_errors; a->rx_crc_errors = b->rx_crc_errors; a->rx_frame_errors = b->rx_frame_errors; a->rx_fifo_errors = b->rx_fifo_errors; a->rx_missed_errors = b->rx_missed_errors; a->tx_aborted_errors = b->tx_aborted_errors; a->tx_carrier_errors = b->tx_carrier_errors; a->tx_fifo_errors = b->tx_fifo_errors; a->tx_heartbeat_errors = b->tx_heartbeat_errors; a->tx_window_errors = b->tx_window_errors; a->rx_compressed = b->rx_compressed; a->tx_compressed = b->tx_compressed; a->rx_nohandler = b->rx_nohandler; }

Contributors

PersonTokensPropCommitsCommitProp
thomas grafthomas graf19995.22%125.00%
jarod wilsonjarod wilson83.83%125.00%
stephen hemmingerstephen hemminger10.48%125.00%
ben hutchingsben hutchings10.48%125.00%
Total209100.00%4100.00%

/* All VF info */
static inline int rtnl_vfinfo_size(const struct net_device *dev, u32 ext_filter_mask) { if (dev->dev.parent && dev_is_pci(dev->dev.parent) && (ext_filter_mask & RTEXT_FILTER_VF)) { int num_vfs = dev_num_vf(dev->dev.parent); size_t size = nla_total_size(sizeof(struct nlattr)); size += nla_total_size(num_vfs * sizeof(struct nlattr)); size += num_vfs * (nla_total_size(sizeof(struct ifla_vf_mac)) + nla_total_size(sizeof(struct ifla_vf_vlan)) + nla_total_size(sizeof(struct ifla_vf_spoofchk)) + nla_total_size(sizeof(struct ifla_vf_rate)) + nla_total_size(sizeof(struct ifla_vf_link_state)) + nla_total_size(sizeof(struct ifla_vf_rss_query_en)) + /* IFLA_VF_STATS_RX_PACKETS */ nla_total_size_64bit(sizeof(__u64)) + /* IFLA_VF_STATS_TX_PACKETS */ nla_total_size_64bit(sizeof(__u64)) + /* IFLA_VF_STATS_RX_BYTES */ nla_total_size_64bit(sizeof(__u64)) + /* IFLA_VF_STATS_TX_BYTES */ nla_total_size_64bit(sizeof(__u64)) + /* IFLA_VF_STATS_BROADCAST */ nla_total_size_64bit(sizeof(__u64)) + /* IFLA_VF_STATS_MULTICAST */ nla_total_size_64bit(sizeof(__u64)) + nla_total_size(sizeof(struct ifla_vf_trust))); return size; } else return 0; }

Contributors

PersonTokensPropCommitsCommitProp
chris wrightchris wright4923.56%19.09%
mitch a williamsmitch a williams4823.08%19.09%
eran ben elishaeran ben elisha4823.08%19.09%
greg rosegreg rose178.17%218.18%
scott feldmanscott feldman115.29%19.09%
jiri bencjiri benc94.33%19.09%
hiroshi shimamotohiroshi shimamoto94.33%19.09%
vladislav zolotarovvladislav zolotarov94.33%19.09%
nicolas dichtelnicolas dichtel62.88%19.09%
sucheta chakrabortysucheta chakraborty20.96%19.09%
Total208100.00%11100.00%


static size_t rtnl_port_size(const struct net_device *dev, u32 ext_filter_mask) { size_t port_size = nla_total_size(4) /* PORT_VF */ + nla_total_size(PORT_PROFILE_MAX) /* PORT_PROFILE */ + nla_total_size(sizeof(struct ifla_port_vsi)) /* PORT_VSI_TYPE */ + nla_total_size(PORT_UUID_MAX) /* PORT_INSTANCE_UUID */ + nla_total_size(PORT_UUID_MAX) /* PORT_HOST_UUID */ + nla_total_size(1) /* PROT_VDP_REQUEST */ + nla_total_size(2); /* PORT_VDP_RESPONSE */ size_t vf_ports_size = nla_total_size(sizeof(struct nlattr)); size_t vf_port_size = nla_total_size(sizeof(struct nlattr)) + port_size; size_t port_self_size = nla_total_size(sizeof(struct nlattr)) + port_size; if (!dev->netdev_ops->ndo_get_vf_port || !dev->dev.parent || !(ext_filter_mask & RTEXT_FILTER_VF)) return 0; if (dev_num_vf(dev->dev.parent)) return port_self_size + vf_ports_size + vf_port_size * dev_num_vf(dev->dev.parent); else return port_self_size; }

Contributors

PersonTokensPropCommitsCommitProp
scott feldmanscott feldman15193.79%150.00%
david gibsondavid gibson106.21%150.00%
Total161100.00%2100.00%


static size_t rtnl_xdp_size(const struct net_device *dev) { size_t xdp_size = nla_total_size(1); /* XDP_ATTACHED */ if (!dev->netdev_ops->ndo_xdp) return 0; else return xdp_size; }

Contributors

PersonTokensPropCommitsCommitProp
brenden blancobrenden blanco37100.00%1100.00%
Total37100.00%1100.00%


static noinline size_t if_nlmsg_size(const struct net_device *dev, u32 ext_filter_mask) { return NLMSG_ALIGN(sizeof(struct ifinfomsg)) + nla_total_size(IFNAMSIZ) /* IFLA_IFNAME */ + nla_total_size(IFALIASZ) /* IFLA_IFALIAS */ + nla_total_size(IFNAMSIZ) /* IFLA_QDISC */ + nla_total_size_64bit(sizeof(struct rtnl_link_ifmap)) + nla_total_size(sizeof(struct rtnl_link_stats)) + nla_total_size_64bit(sizeof(struct rtnl_link_stats64)) + nla_total_size(MAX_ADDR_LEN) /* IFLA_ADDRESS */ + nla_total_size(MAX_ADDR_LEN) /* IFLA_BROADCAST */ + nla_total_size(4) /* IFLA_TXQLEN */ + nla_total_size(4) /* IFLA_WEIGHT */ + nla_total_size(4) /* IFLA_MTU */ + nla_total_size(4) /* IFLA_LINK */ + nla_total_size(4) /* IFLA_MASTER */ + nla_total_size(1) /* IFLA_CARRIER */ + nla_total_size(4) /* IFLA_PROMISCUITY */ + nla_total_size(4) /* IFLA_NUM_TX_QUEUES */ + nla_total_size(4) /* IFLA_NUM_RX_QUEUES */ + nla_total_size(4) /* IFLA_MAX_GSO_SEGS */ + nla_total_size(4) /* IFLA_MAX_GSO_SIZE */ + nla_total_size(1) /* IFLA_OPERSTATE */ + nla_total_size(1) /* IFLA_LINKMODE */ + nla_total_size(4) /* IFLA_CARRIER_CHANGES */ + nla_total_size(4) /* IFLA_LINK_NETNSID */ + nla_total_size(ext_filter_mask & RTEXT_FILTER_VF ? 4 : 0) /* IFLA_NUM_VF */ + rtnl_vfinfo_size(dev, ext_filter_mask) /* IFLA_VFINFO_LIST */ + rtnl_port_size(dev, ext_filter_mask) /* IFLA_VF_PORTS + IFLA_PORT_SELF */ + rtnl_link_get_size(dev) /* IFLA_LINKINFO */ + rtnl_link_get_af_size(dev, ext_filter_mask) /* IFLA_AF_SPEC */ + nla_total_size(MAX_PHYS_ITEM_ID_LEN) /* IFLA_PHYS_PORT_ID */ + nla_total_size(MAX_PHYS_ITEM_ID_LEN) /* IFLA_PHYS_SWITCH_ID */ + nla_total_size(IFNAMSIZ) /* IFLA_PHYS_PORT_NAME */ + rtnl_xdp_size(dev) /* IFLA_XDP */ + nla_total_size(1); /* IFLA_PROTO_DOWN */ }

Contributors

PersonTokensPropCommitsCommitProp
thomas grafthomas graf9337.96%28.00%
scott feldmanscott feldman3413.88%14.00%
jiri pirkojiri pirko3012.24%520.00%
eric dumazeteric dumazet135.31%28.00%
nicolas dichtelnicolas dichtel135.31%312.00%
greg rosegreg rose114.49%14.00%
jan engelhardtjan engelhardt93.67%14.00%
anuradha karuppiahanuradha karuppiah72.86%14.00%
brenden blancobrenden blanco62.45%14.00%
ben greearben greear62.45%14.00%
stephen hemmingerstephen hemminger62.45%14.00%
david decotignydavid decotigny62.45%14.00%
patrick mchardypatrick mchardy52.04%14.00%
ronen aradronen arad20.82%14.00%
david gibsondavid gibson20.82%14.00%
david s. millerdavid s. miller20.82%28.00%
Total245100.00%25100.00%


static int rtnl_vf_ports_fill(struct sk_buff *skb, struct net_device *dev) { struct nlattr *vf_ports; struct nlattr *vf_port; int vf; int err; vf_ports = nla_nest_start(skb, IFLA_VF_PORTS); if (!vf_ports) return -EMSGSIZE; for (vf = 0; vf < dev_num_vf(dev->dev.parent); vf++) { vf_port = nla_nest_start(skb, IFLA_VF_PORT); if (!vf_port) goto nla_put_failure; if (nla_put_u32(skb, IFLA_PORT_VF, vf)) goto nla_put_failure; err = dev->netdev_ops->ndo_get_vf_port(dev, vf, skb); if (err == -EMSGSIZE) goto nla_put_failure; if (err) { nla_nest_cancel(skb, vf_port); continue; } nla_nest_end(skb, vf_port); } nla_nest_end(skb, vf_ports); return 0; nla_put_failure: nla_nest_cancel(skb, vf_ports); return -EMSGSIZE; }

Contributors

PersonTokensPropCommitsCommitProp
scott feldmanscott feldman16595.93%266.67%
david s. millerdavid s. miller74.07%133.33%
Total172100.00%3100.00%


static int rtnl_port_self_fill(struct sk_buff *skb, struct net_device *dev) { struct nlattr *port_self; int err; port_self = nla_nest_start(skb, IFLA_PORT_SELF); if (!port_self) return -EMSGSIZE; err = dev->netdev_ops->ndo_get_vf_port(dev, PORT_SELF_VF, skb); if (err) { nla_nest_cancel(skb, port_self); return (err == -EMSGSIZE) ? err : 0; } nla_nest_end(skb, port_self); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
scott feldmanscott feldman8996.74%266.67%
thomas grafthomas graf33.26%133.33%
Total92100.00%3100.00%


static int rtnl_port_fill(struct sk_buff *skb, struct net_device *dev, u32 ext_filter_mask) { int err; if (!dev->netdev_ops->ndo_get_vf_port || !dev->dev.parent || !(ext_filter_mask & RTEXT_FILTER_VF)) return 0; err = rtnl_port_self_fill(skb, dev); if (err) return err; if (dev_num_vf(dev->dev.parent)) { err = rtnl_vf_ports_fill(skb, dev); if (err) return err; } return 0; }

Contributors

PersonTokensPropCommitsCommitProp
scott feldmanscott feldman7679.17%120.00%
david gibsondavid gibson1010.42%120.00%
mitch a williamsmitch a williams55.21%120.00%
patrick mchardypatrick mchardy44.17%120.00%
thomas grafthomas graf11.04%120.00%
Total96100.00%5100.00%


static int rtnl_phys_port_id_fill(struct sk_buff *skb, struct net_device *dev) { int err; struct netdev_phys_item_id ppid; err = dev_get_phys_port_id(dev, &ppid); if (err) { if (err == -EOPNOTSUPP) return 0; return err; } if (nla_put(skb, IFLA_PHYS_PORT_ID, ppid.id_len, ppid.id)) return -EMSGSIZE; return 0; }

Contributors

PersonTokensPropCommitsCommitProp
jiri pirkojiri pirko76100.00%2100.00%
Total76100.00%2100.00%


static int rtnl_phys_port_name_fill(struct sk_buff *skb, struct net_device *dev) { char name[IFNAMSIZ]; int err; err = dev_get_phys_port_name(dev, name, sizeof(name)); if (err) { if (err == -EOPNOTSUPP) return 0; return err; } if (nla_put(skb, IFLA_PHYS_PORT_NAME, strlen(name), name)) return -EMSGSIZE; return 0; }

Contributors

PersonTokensPropCommitsCommitProp
david aherndavid ahern81100.00%1100.00%
Total81100.00%1100.00%


static int rtnl_phys_switch_id_fill(struct sk_buff *skb, struct net_device *dev) { int err; struct switchdev_attr attr = { .orig_dev = dev, .id = SWITCHDEV_ATTR_ID_PORT_PARENT_ID, .flags = SWITCHDEV_F_NO_RECURSE, }; err = switchdev_port_attr_get(dev, &attr); if (err) { if (err == -EOPNOTSUPP) return 0; return err; } if (nla_put(skb, IFLA_PHYS_SWITCH_ID, attr.u.ppid.id_len, attr.u.ppid.id)) return -EMSGSIZE; return 0; }

Contributors

PersonTokensPropCommitsCommitProp
jiri pirkojiri pirko7170.30%240.00%
scott feldmanscott feldman2524.75%240.00%
ido schimmelido schimmel54.95%120.00%
Total101100.00%5100.00%


static noinline_for_stack int rtnl_fill_stats(struct sk_buff *skb, struct net_device *dev) { struct rtnl_link_stats64 *sp; struct nlattr *attr; attr = nla_reserve_64bit(skb, IFLA_STATS64, sizeof(struct rtnl_link_stats64), IFLA_PAD); if (!attr) return -EMSGSIZE; sp = nla_data(attr); dev_get_stats(dev, sp); attr = nla_reserve(skb, IFLA_STATS, sizeof(struct rtnl_link_stats)); if (!attr) return -EMSGSIZE; copy_rtnl_link_stats(nla_data(attr), sp); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
hannes frederic sowahannes frederic sowa3230.77%18.33%
patrick mchardypatrick mchardy2826.92%18.33%
pre-gitpre-git1716.35%325.00%
roopa prabhuroopa prabhu1413.46%18.33%
pavel emelianovpavel emelianov43.85%18.33%
nicolas dichtelnicolas dichtel32.88%18.33%
ben greearben greear21.92%18.33%
dogaru vladdogaru vlad21.92%18.33%
eric dumazeteric dumazet10.96%18.33%
thomas grafthomas graf10.96%18.33%
Total104100.00%12100.00%


static noinline_for_stack int rtnl_fill_vfinfo(struct sk_buff *skb, struct net_device *dev, int vfs_num, struct nlattr *vfinfo) { struct ifla_vf_rss_query_en vf_rss_query_en; struct ifla_vf_link_state vf_linkstate; struct ifla_vf_spoofchk vf_spoofchk; struct ifla_vf_tx_rate vf_tx_rate; struct ifla_vf_stats vf_stats; struct ifla_vf_trust vf_trust; struct ifla_vf_vlan vf_vlan; struct ifla_vf_rate vf_rate; struct nlattr *vf, *vfstats; struct ifla_vf_mac vf_mac; struct ifla_vf_info ivi; /* Not all SR-IOV capable drivers support the * spoofcheck and "RSS query enable" query. Preset to * -1 so the user space tool can detect that the driver * didn't report anything. */ ivi.spoofchk = -1; ivi.rss_query_en = -1; ivi.trusted = -1; memset(ivi.mac, 0, sizeof(ivi.mac)); /* The default value for VF link state is "auto" * IFLA_VF_LINK_STATE_AUTO which equals zero */ ivi.linkstate = 0; if (dev->netdev_ops->ndo_get_vf_config(dev, vfs_num, &ivi)) return 0; vf_mac.vf = vf_vlan.vf = vf_rate.vf = vf_tx_rate.vf = vf_spoofchk.vf = vf_linkstate.vf = vf_rss_query_en.vf = vf_trust.vf = ivi.vf; memcpy(vf_mac.mac, ivi.mac, sizeof(ivi.mac)); vf_vlan.vlan = ivi.vlan; vf_vlan.qos = ivi.qos; vf_tx_rate.rate = ivi.max_tx_rate; vf_rate.min_tx_rate = ivi.min_tx_rate; vf_rate.max_tx_rate = ivi.max_tx_rate; vf_spoofchk.setting = ivi.spoofchk; vf_linkstate.link_state = ivi.linkstate; vf_rss_query_en.setting = ivi.rss_query_en; vf_trust.setting = ivi.trusted; vf = nla_nest_start(skb, IFLA_VF_INFO); if (!vf) { nla_nest_cancel(skb, vfinfo); return -EMSGSIZE; } if (nla_put(skb, IFLA_VF_MAC, sizeof(vf_mac), &vf_mac) || nla_put(skb, IFLA_VF_VLAN, sizeof(vf_vlan), &vf_vlan) || nla_put(skb, IFLA_VF_RATE, sizeof(vf_rate), &vf_rate) || nla_put(skb, IFLA_VF_TX_RATE, sizeof(vf_tx_rate), &vf_tx_rate) || nla_put(skb, IFLA_VF_SPOOFCHK, sizeof(vf_spoofchk), &vf_spoofchk) || nla_put(skb, IFLA_VF_LINK_STATE, sizeof(vf_linkstate), &vf_linkstate) || nla_put(skb, IFLA_VF_RSS_QUERY_EN, sizeof(vf_rss_query_en), &vf_rss_query_en) || nla_put(skb, IFLA_VF_TRUST, sizeof(vf_trust), &vf_trust)) return -EMSGSIZE; memset(&vf_stats, 0, sizeof(vf_stats)); if (dev->netdev_ops->ndo_get_vf_stats) dev->netdev_ops->ndo_get_vf_stats(dev, vfs_num, &vf_stats); vfstats = nla_nest_start(skb, IFLA_VF_STATS); if (!vfstats) { nla_nest_cancel(skb, vf); nla_nest_cancel(skb, vfinfo); return -EMSGSIZE; } if (nla_put_u64_64bit(skb, IFLA_VF_STATS_RX_PACKETS, vf_stats.rx_packets, IFLA_VF_STATS_PAD) || nla_put_u64_64bit(skb, IFLA_VF_STATS_TX_PACKETS, vf_stats.tx_packets, IFLA_VF_STATS_PAD) || nla_put_u64_64bit(skb, IFLA_VF_STATS_RX_BYTES, vf_stats.rx_bytes, IFLA_VF_STATS_PAD) || nla_put_u64_64bit(skb, IFLA_VF_STATS_TX_BYTES, vf_stats.tx_bytes, IFLA_VF_STATS_PAD) || nla_put_u64_64bit(skb, IFLA_VF_STATS_BROADCAST, vf_stats.broadcast, IFLA_VF_STATS_PAD) || nla_put_u64_64bit(skb, IFLA_VF_STATS_MULTICAST, vf_stats.multicast, IFLA_VF_STATS_PAD)) return -EMSGSIZE; nla_nest_end(skb, vfstats); nla_nest_end(skb, vf); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
hannes frederic sowahannes frederic sowa44375.60%15.88%
patrick mchardypatrick mchardy498.36%15.88%
jiri pirkojiri pirko233.92%423.53%
nicolas dichtelnicolas dichtel223.75%211.76%
jan engelhardtjan engelhardt122.05%15.88%
david decotignydavid decotigny81.37%15.88%
david s. millerdavid s. miller61.02%15.88%
anuradha karuppiahanuradha karuppiah61.02%15.88%
david aherndavid ahern61.02%15.88%
stephen hemmingerstephen hemminger50.85%15.88%
scott feldmanscott feldman30.51%15.88%
pavel emelianovpavel emelianov20.34%15.88%
eric dumazeteric dumazet10.17%15.88%
Total586100.00%17100.00%


static int rtnl_fill_link_ifmap(struct sk_buff *skb, struct net_device *dev) { struct rtnl_link_ifmap map; memset(&map, 0, sizeof(map)); map.mem_start = dev->mem_start; map.mem_end = dev->mem_end; map.base_addr = dev->base_addr; map.irq = dev->irq; map.dma = dev->dma; map.port = dev->if_port; if (nla_put_64bit(skb, IFLA_MAP, sizeof(map), &map, IFLA_PAD)) return -EMSGSIZE; return 0; }

Contributors

PersonTokensPropCommitsCommitProp
hannes frederic sowahannes frederic sowa6056.07%116.67%
kangjie lukangjie lu2624.30%116.67%
mitch a williamsmitch a williams98.41%116.67%
chris wrightchris wright54.67%116.67%
scott feldmanscott feldman43.74%116.67%
nicolas dichtelnicolas dichtel32.80%116.67%
Total107100.00%6100.00%


static int rtnl_xdp_fill(struct sk_buff *skb, struct net_device *dev) { struct netdev_xdp xdp_op = {}; struct nlattr *xdp; int err; if (!dev->netdev_ops->ndo_xdp) return 0; xdp = nla_nest_start(skb, IFLA_XDP); if (!xdp) return -EMSGSIZE; xdp_op.command = XDP_QUERY_PROG; err = dev->netdev_ops->ndo_xdp(dev, &xdp_op); if (err) goto err_cancel; err = nla_put_u8(skb, IFLA_XDP_ATTACHED, xdp_op.prog_attached); if (err) goto err_cancel; nla_nest_end(skb, xdp); return 0; err_cancel: nla_nest_cancel(skb, xdp); return err; }

Contributors

PersonTokensPropCommitsCommitProp
brenden blancobrenden blanco129100.00%1100.00%
Total129100.00%1100.00%


static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev, int type, u32 pid, u32 seq, u32 change, unsigned int flags, u32 ext_filter_mask) { struct ifinfomsg *ifm; struct nlmsghdr *nlh; struct nlattr *af_spec; struct rtnl_af_ops *af_ops; struct net_device *upper_dev = netdev_master_upper_dev_get(dev); ASSERT_RTNL(); nlh = nlmsg_put(skb, pid, seq, type, sizeof(*ifm), flags); if (nlh == NULL) return -EMSGSIZE; ifm = nlmsg_data(nlh); ifm->ifi_family = AF_UNSPEC; ifm->__ifi_pad = 0; ifm->ifi_type = dev->type; ifm->ifi_index = dev->ifindex; ifm->ifi_flags = dev_get_flags(dev); ifm->ifi_change = change; if (nla_put_string(skb, IFLA_IFNAME, dev->name) || nla_put_u32(skb, IFLA_TXQLEN, dev->tx_queue_len) || nla_put_u8(skb, IFLA_OPERSTATE, netif_running(dev) ? dev->operstate : IF_OPER_DOWN) || nla_put_u8(skb, IFLA_LINKMODE, dev->link_mode) || nla_put_u32(skb, IFLA_MTU, dev->mtu) || nla_put_u32(skb, IFLA_GROUP, dev->group) || nla_put_u32(skb, IFLA_PROMISCUITY, dev->promiscuity) || nla_put_u32(skb, IFLA_NUM_TX_QUEUES, dev->num_tx_queues) || nla_put_u32(skb, IFLA_GSO_MAX_SEGS, dev->gso_max_segs) || nla_put_u32(skb, IFLA_GSO_MAX_SIZE, dev->gso_max_size) || #ifdef CONFIG_RPS nla_put_u32(skb, IFLA_NUM_RX_QUEUES, dev->num_rx_queues) || #endif (dev->ifindex != dev_get_iflink(dev) && nla_put_u32(skb, IFLA_LINK, dev_get_iflink(dev))) || (upper_dev && nla_put_u32(skb, IFLA_MASTER, upper_dev->ifindex)) || nla_put_u8(skb, IFLA_CARRIER, netif_carrier_ok(dev)) || (dev->qdisc && nla_put_string(skb, IFLA_QDISC, dev->qdisc->ops->id)) || (dev->ifalias && nla_put_string(skb, IFLA_IFALIAS, dev->ifalias)) || nla_put_u32(skb, IFLA_CARRIER_CHANGES, atomic_read(&dev->carrier_changes)) || nla_put_u8(skb, IFLA_PROTO_DOWN, dev->proto_down)) goto nla_put_failure; if (rtnl_fill_link_ifmap(skb, dev)) goto nla_put_failure; if (dev->addr_len) { if (nla_put(skb, IFLA_ADDRESS, dev->addr_len, dev->dev_addr) || nla_put(skb, IFLA_BROADCAST, dev->addr_len, dev->broadcast)) goto nla_put_failure; } if (rtnl_phys_port_id_fill(skb, dev)) goto nla_put_failure; if (rtnl_phys_port_name_fill(skb, dev)) goto nla_put_failure; if (rtnl_phys_switch_id_fill(skb, dev)) goto nla_put_failure; if (rtnl_fill_stats(skb, dev)) goto nla_put_failure; if (dev->dev.parent && (ext_filter_mask & RTEXT_FILTER_VF) && nla_put_u32(skb, IFLA_NUM_VF, dev_num_vf(dev->dev.parent))) goto nla_put_failure; if (dev->netdev_ops->ndo_get_vf_config && dev->dev.parent && ext_filter_mask & RTEXT_FILTER_VF) { int i; struct nlattr *vfinfo; int num_vfs = dev_num_vf(dev->dev.parent); vfinfo = nla_nest_start(skb, IFLA_VFINFO_LIST); if (!vfinfo) goto nla_put_failure; for (i = 0; i < num_vfs; i++) { if (rtnl_fill_vfinfo(skb, dev, i, vfinfo)) goto nla_put_failure; } nla_nest_end(skb, vfinfo); } if (rtnl_port_fill(skb, dev, ext_filter_mask)) goto nla_put_failure; if (rtnl_xdp_fill(skb, dev)) goto nla_put_failure; if (dev->rtnl_link_ops || rtnl_have_link_slave_info(dev)) { if (rtnl_link_fill(skb, dev) < 0) goto nla_put_failure; } if (dev->rtnl_link_ops && dev->rtnl_link_ops->get_link_net) { struct net *link_net = dev->rtnl_link_ops->get_link_net(dev); if (!net_eq(dev_net(dev), link_net)) { int id = peernet2id_alloc(dev_net(dev), link_net); if (nla_put_s32(skb, IFLA_LINK_NETNSID, id)) goto nla_put_failure; } } if (!(af_spec = nla_nest_start(skb, IFLA_AF_SPEC))) goto nla_put_failure; list_for_each_entry(af_ops, &rtnl_af_ops, list) { if (af_ops->fill_link_af) { struct nlattr *af; int err; if (!(af = nla_nest_start(skb, af_ops->family))) goto nla_put_failure; err = af_ops->fill_link_af(skb, dev, ext_filter_mask); /* * Caller may return ENODATA to indicate that there * was no data to be dumped. This is not an error, it * means we should trim the attribute header and * continue. */ if (err == -ENODATA) nla_nest_cancel(skb, af); else if (err < 0) goto nla_put_failure; nla_nest_end(skb, af); } } nla_nest_end(skb, af_spec); nlmsg_end(skb, nlh); return 0; nla_put_failure: nlmsg_cancel(skb, nlh); return -EMSGSIZE; }

Contributors

PersonTokensPropCommitsCommitProp
hannes frederic sowahannes frederic sowa42347.42%14.55%
thomas grafthomas graf11212.56%14.55%
nicolas dichtelnicolas dichtel707.85%29.09%
eran ben elishaeran ben elisha626.95%14.55%
patrick mchardypatrick mchardy394.37%14.55%
chris wrightchris wright384.26%14.55%
eric dumazeteric dumazet222.47%14.55%
hiroshi shimamotohiroshi shimamoto151.68%14.55%
mitch a williamsmitch a williams141.57%14.55%
vladislav zolotarovvladislav zolotarov131.46%14.55%
greg rosegreg rose121.35%14.55%
scott feldmanscott feldman121.35%14.55%
brenden blancobrenden blanco121.35%14.55%
rony efraimrony efraim111.23%14.55%
sucheta chakrabortysucheta chakraborty101.12%14.55%
mathias krausemathias krause80.90%14.55%
david s. millerdavid s. miller70.78%14.55%
jiri pirkojiri pirko50.56%14.55%
johannes bergjohannes berg30.34%14.55%
sowmini varadhansowmini varadhan20.22%14.55%
david gibsondavid gibson20.22%14.55%
Total892100.00%22100.00%

static const struct nla_policy ifla_policy[IFLA_MAX+1] = { [IFLA_IFNAME] = { .type = NLA_STRING, .len = IFNAMSIZ-1 }, [IFLA_ADDRESS] = { .type = NLA_BINARY, .len = MAX_ADDR_LEN }, [IFLA_BROADCAST] = { .type = NLA_BINARY, .len = MAX_ADDR_LEN }, [IFLA_MAP] = { .len = sizeof(struct rtnl_link_ifmap) }, [IFLA_MTU] = { .type = NLA_U32 }, [IFLA_LINK] = { .type = NLA_U32 }, [IFLA_MASTER] = { .type = NLA_U32 }, [IFLA_CARRIER] = { .type = NLA_U8 }, [IFLA_TXQLEN] = { .type = NLA_U32 }, [IFLA_WEIGHT] = { .type = NLA_U32 }, [IFLA_OPERSTATE] = { .type = NLA_U8 }, [IFLA_LINKMODE] = { .type = NLA_U8 }, [IFLA_LINKINFO] = { .type = NLA_NESTED }, [IFLA_NET_NS_PID] = { .type = NLA_U32 }, [IFLA_NET_NS_FD] = { .type = NLA_U32 }, [IFLA_IFALIAS] = { .type = NLA_STRING, .len = IFALIASZ-1 }, [IFLA_VFINFO_LIST] = {. type = NLA_NESTED }, [IFLA_VF_PORTS] = { .type = NLA_NESTED }, [IFLA_PORT_SELF] = { .type = NLA_NESTED }, [IFLA_AF_SPEC] = { .type = NLA_NESTED }, [IFLA_EXT_MASK] = { .type = NLA_U32 }, [IFLA_PROMISCUITY] = { .type = NLA_U32 }, [IFLA_NUM_TX_QUEUES] = { .type = NLA_U32 }, [IFLA_NUM_RX_QUEUES] = { .type = NLA_U32 }, [IFLA_PHYS_PORT_ID] = { .type = NLA_BINARY, .len = MAX_PHYS_ITEM_ID_LEN }, [IFLA_CARRIER_CHANGES] = { .type = NLA_U32 }, /* ignored */ [IFLA_PHYS_SWITCH_ID] = { .type = NLA_BINARY, .len = MAX_PHYS_ITEM_ID_LEN }, [IFLA_LINK_NETNSID] = { .type = NLA_S32 }, [IFLA_PROTO_DOWN] = { .type = NLA_U8 }, [IFLA_XDP] = { .type = NLA_NESTED }, }; static const struct nla_policy ifla_info_policy[IFLA_INFO_MAX+1] = { [IFLA_INFO_KIND] = { .type = NLA_STRING }, [IFLA_INFO_DATA] = { .type = NLA_NESTED }, [IFLA_INFO_SLAVE_KIND] = { .type = NLA_STRING }, [IFLA_INFO_SLAVE_DATA] = { .type = NLA_NESTED }, }; static const struct nla_policy ifla_vf_policy[IFLA_VF_MAX+1] = { [IFLA_VF_MAC] = { .len = sizeof(struct ifla_vf_mac) }, [IFLA_VF_VLAN] = { .len = sizeof(struct ifla_vf_vlan) }, [IFLA_VF_TX_RATE] = { .len = sizeof(struct ifla_vf_tx_rate) }, [IFLA_VF_SPOOFCHK] = { .len = sizeof(struct ifla_vf_spoofchk) }, [IFLA_VF_RATE] = { .len = sizeof(struct ifla_vf_rate) }, [IFLA_VF_LINK_STATE] = { .len = sizeof(struct ifla_vf_link_state) }, [IFLA_VF_RSS_QUERY_EN] = { .len = sizeof(struct ifla_vf_rss_query_en) }, [IFLA_VF_STATS] = { .type = NLA_NESTED }, [IFLA_VF_TRUST] = { .len = sizeof(struct ifla_vf_trust) }, [IFLA_VF_IB_NODE_GUID] = { .len = sizeof(struct ifla_vf_guid) }, [IFLA_VF_IB_PORT_GUID] = { .len = sizeof(struct ifla_vf_guid) }, }; static const struct nla_policy ifla_port_policy[IFLA_PORT_MAX+1] = { [IFLA_PORT_VF] = { .type = NLA_U32 }, [IFLA_PORT_PROFILE] = { .type = NLA_STRING, .len = PORT_PROFILE_MAX }, [IFLA_PORT_VSI_TYPE] = { .type = NLA_BINARY, .len = sizeof(struct ifla_port_vsi)}, [IFLA_PORT_INSTANCE_UUID] = { .type = NLA_BINARY, .len = PORT_UUID_MAX }, [IFLA_PORT_HOST_UUID] = { .type = NLA_STRING, .len = PORT_UUID_MAX }, [IFLA_PORT_REQUEST] = { .type = NLA_U8, }, [IFLA_PORT_RESPONSE] = { .type = NLA_U16, }, }; static const struct nla_policy ifla_xdp_policy[IFLA_XDP_MAX + 1] = { [IFLA_XDP_FD] = { .type = NLA_S32 }, [IFLA_XDP_ATTACHED] = { .type = NLA_U8 }, };
static const struct rtnl_link_ops *linkinfo_to_kind_ops(const struct nlattr *nla) { const struct rtnl_link_ops *ops = NULL; struct nlattr *linfo[IFLA_INFO_MAX + 1]; if (nla_parse_nested(linfo, IFLA_INFO_MAX, nla, ifla_info_policy) < 0) return NULL; if (linfo[IFLA_INFO_KIND]) { char kind[MODULE_NAME_LEN]; nla_strlcpy(kind, linfo[IFLA_INFO_KIND], sizeof(kind)); ops = rtnl_link_ops_get(kind); } return ops; }

Contributors

PersonTokensPropCommitsCommitProp
david aherndavid ahern91100.00%1100.00%
Total91100.00%1100.00%


static bool link_master_filtered(struct net_device *dev, int master_idx) { struct net_device *master; if (!master_idx) return false; master = netdev_master_upper_dev_get(dev); if (!master || master->ifindex != master_idx) return true; return false; }

Contributors

PersonTokensPropCommitsCommitProp
david aherndavid ahern51100.00%1100.00%
Total51100.00%1100.00%


static bool link_kind_filtered(const struct net_device *dev, const struct rtnl_link_ops *kind_ops) { if (kind_ops && dev->rtnl_link_ops != kind_ops) return true; return false; }

Contributors

PersonTokensPropCommitsCommitProp
david aherndavid ahern34100.00%1100.00%
Total34100.00%1100.00%


static bool link_dump_filtered(struct net_device *dev, int master_idx, const struct rtnl_link_ops *kind_ops) { if (link_master_filtered(dev, master_idx) || link_kind_filtered(dev, kind_ops)) return true; return false; }

Contributors

PersonTokensPropCommitsCommitProp
david aherndavid ahern42100.00%1100.00%
Total42100.00%1100.00%


static int rtnl_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb) { struct net *net = sock_net(skb->sk); int h, s_h; int idx = 0, s_idx; struct net_device *dev; struct hlist_head *head; struct nlattr *tb[IFLA_MAX+1]; u32 ext_filter_mask = 0; const struct rtnl_link_ops *kind_ops = NULL; unsigned int flags = NLM_F_MULTI; int master_idx = 0; int err; int hdrlen; s_h = cb->args[0]; s_idx = cb->args[1]; cb->seq = net->dev_base_seq; /* A hack to preserve kernel<->userspace interface. * The correct header is ifinfomsg. It is consistent with rtnl_getlink. * However, before Linux v3.9 the code here assumed rtgenmsg and that's * what iproute2 < v3.9.0 used. * We can detect the old iproute2. Even including the IFLA_EXT_MASK * attribute, its netlink message is shorter than struct ifinfomsg. */ hdrlen = nlmsg_len(cb->nlh) < sizeof(struct ifinfomsg) ? sizeof(struct rtgenmsg) : sizeof(struct ifinfomsg); if (nlmsg_parse(cb->nlh, hdrlen, tb, IFLA_MAX, ifla_policy) >= 0) { if (tb[IFLA_EXT_MASK]) ext_filter_mask = nla_get_u32(tb[IFLA_EXT_MASK]); if (tb[IFLA_MASTER]) master_idx = nla_get_u32(tb[IFLA_MASTER]); if (tb[IFLA_LINKINFO]) kind_ops = linkinfo_to_kind_ops(tb[IFLA_LINKINFO]); if (master_idx || kind_ops) flags |= NLM_F_DUMP_FILTERED; } for (h = s_h; h < NETDEV_HASHENTRIES; h++, s_idx = 0) { idx = 0; head = &net->dev_index_head[h]; hlist_for_each_entry(dev, head, index_hlist) { if (link_dump_filtered(dev, master_idx, kind_ops)) continue; if (idx < s_idx) goto cont; err = rtnl_fill_ifinfo(skb, dev, RTM_NEWLINK, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq, 0, flags, ext_filter_mask); /* If we ran out of room on the first message, * we're in trouble */ WARN_ON((err == -EMSGSIZE) && (skb->len == 0)); if (err < 0) goto out; nl_dump_check_consistent(cb, nlmsg_hdr(skb)); cont: idx++; } } out: cb->args[1] = idx; cb->args[0] = h; return skb->len; }

Contributors

PersonTokensPropCommitsCommitProp
jiri pirkojiri pirko25364.87%116.67%
david aherndavid ahern7619.49%116.67%
michal schmidtmichal schmidt317.95%116.67%
david gibsondavid gibson287.18%116.67%
david s. millerdavid s. miller10.26%116.67%
eric dumazeteric dumazet10.26%116.67%
Total390100.00%6100.00%


int rtnl_nla_parse_ifla(struct nlattr **tb, const struct nlattr *head, int len) { return nla_parse(tb, IFLA_MAX, head, len, ifla_policy); }

Contributors

PersonTokensPropCommitsCommitProp
jiri pirkojiri pirko34100.00%1100.00%
Total34100.00%1100.00%

EXPORT_SYMBOL(rtnl_nla_parse_ifla);
struct net *rtnl_link_get_net(struct net *src_net, struct nlattr *tb[]) { struct net *net; /* Examine the link attributes and figure out which * network namespace we are talking about. */ if (tb[IFLA_NET_NS_PID]) net = get_net_ns_by_pid(nla_get_u32(tb[IFLA_NET_NS_PID])); else if (tb[IFLA_NET_NS_FD]) net = get_net_ns_by_fd(nla_get_u32(tb[IFLA_NET_NS_FD])); else net = get_net(src_net); return net; }

Contributors

PersonTokensPropCommitsCommitProp
eric w. biedermaneric w. biederman76100.00%2100.00%
Total76100.00%2100.00%

EXPORT_SYMBOL(rtnl_link_get_net);
static int validate_linkmsg(struct net_device *dev, struct nlattr *tb[]) { if (dev) { if (tb[IFLA_ADDRESS] && nla_len(tb[IFLA_ADDRESS]) < dev->addr_len) return -EINVAL; if (tb[IFLA_BROADCAST] && nla_len(tb[IFLA_BROADCAST]) < dev->addr_len) return -EINVAL; } if (tb[IFLA_AF_SPEC]) { struct nlattr *af; int rem, err; nla_for_each_nested(af, tb[IFLA_AF_SPEC], rem) { const struct rtnl_af_ops *af_ops; if (!(af_ops = rtnl_af_lookup(nla_type(af)))) return -EAFNOSUPPORT; if (!af_ops->set_link_af) return -EOPNOTSUPP; if (af_ops->validate_link_af) { err = af_ops->validate_link_af(dev, af); if (err < 0) return err; } } } return 0; }

Contributors

PersonTokensPropCommitsCommitProp
thomas grafthomas graf16499.39%266.67%
kurt van dijckkurt van dijck10.61%133.33%
Total165100.00%3100.00%


static int handle_infiniband_guid(struct net_device *dev, struct ifla_vf_guid *ivt, int guid_type) { const struct net_device_ops *ops = dev->netdev_ops; return ops->ndo_set_vf_guid(dev, ivt->vf, ivt->guid, guid_type); }

Contributors

PersonTokensPropCommitsCommitProp
eli coheneli cohen47100.00%1100.00%
Total47100.00%1100.00%


static int handle_vf_guid(struct net_device *dev, struct ifla_vf_guid *ivt, int guid_type) { if (dev->type != ARPHRD_INFINIBAND) return -EOPNOTSUPP; return handle_infiniband_guid(dev, ivt, guid_type); }

Contributors

PersonTokensPropCommitsCommitProp
eli coheneli cohen41100.00%1100.00%
Total41100.00%1100.00%


static int do_setvfinfo(struct net_device *dev, struct nlattr **tb) { const struct net_device_ops *ops = dev->netdev_ops; int err = -EINVAL; if (tb[IFLA_VF_MAC]) { struct ifla_vf_mac *ivm = nla_data(tb[IFLA_VF_MAC]); err = -EOPNOTSUPP; if (ops->ndo_set_vf_mac) err = ops->ndo_set_vf_mac(dev, ivm->vf, ivm->mac); if (err < 0) return err; } if (tb[IFLA_VF_VLAN]) { struct ifla_vf_vlan *ivv = nla_data(tb[IFLA_VF_VLAN]); err = -EOPNOTSUPP; if (ops->ndo_set_vf_vlan) err = ops->ndo_set_vf_vlan(dev, ivv->vf, ivv->vlan, ivv->qos); if (err < 0) return err; } if (tb[IFLA_VF_TX_RATE]) { struct ifla_vf_tx_rate *ivt = nla_data(tb[IFLA_VF_TX_RATE]); struct ifla_vf_info ivf; err = -EOPNOTSUPP; if (ops->ndo_get_vf_config) err = ops->ndo_get_vf_config(dev, ivt->vf, &ivf); if (err < 0) return err; err = -EOPNOTSUPP; if (ops->ndo_set_vf_rate) err = ops->ndo_set_vf_rate(dev, ivt->vf, ivf.min_tx_rate, ivt->rate); if (err < 0) return err; } if (tb[IFLA_VF_RATE]) { struct ifla_vf_rate *ivt = nla_data(tb[IFLA_VF_RATE]); err = -EOPNOTSUPP; if (ops->ndo_set_vf_rate) err = ops->ndo_set_vf_rate(dev, ivt->vf, ivt->min_tx_rate, ivt->max_tx_rate); if (err < 0) return err; } if (tb[IFLA_VF_SPOOFCHK]) { struct ifla_vf_spoofchk *ivs = nla_data(tb[IFLA_VF_SPOOFCHK]); err = -EOPNOTSUPP; if (ops->ndo_set_vf_spoofchk) err = ops->ndo_set_vf_spoofchk(dev, ivs->vf, ivs->setting); if (err < 0) return err; } if (tb[IFLA_VF_LINK_STATE]) { struct ifla_vf_link_state *ivl = nla_data(tb[IFLA_VF_LINK_STATE]); err = -EOPNOTSUPP; if (ops->ndo_set_vf_link_state) err = ops->ndo_set_vf_link_state(dev, ivl->vf, ivl->link_state); if (err < 0) return err; } if (tb[IFLA_VF_RSS_QUERY_EN]) { struct ifla_vf_rss_query_en *ivrssq_en; err = -EOPNOTSUPP; ivrssq_en = nla_data(tb[IFLA_VF_RSS_QUERY_EN]); if (ops->ndo_set_vf_rss_query_en) err = ops->ndo_set_vf_rss_query_en(dev, ivrssq_en->vf, ivrssq_en->setting); if (err < 0) return err; } if (tb[IFLA_VF_TRUST]) { struct ifla_vf_trust *ivt = nla_data(tb[IFLA_VF_TRUST]); err = -EOPNOTSUPP; if (ops->ndo_set_vf_trust) err = ops->ndo_set_vf_trust(dev, ivt->vf, ivt->setting); if (err < 0) return err; } if (tb[IFLA_VF_IB_NODE_GUID]) { struct ifla_vf_guid *ivt = nla_data(tb[IFLA_VF_IB_NODE_GUID]); if (!ops->ndo_set_vf_guid) return -EOPNOTSUPP; return handle_vf_guid(dev, ivt, IFLA_VF_IB_NODE_GUID); } if (tb[IFLA_VF_IB_PORT_GUID]) { struct ifla_vf_guid *ivt = nla_data(tb[IFLA_VF_IB_PORT_GUID]); if (!ops->ndo_set_vf_guid) return -EOPNOTSUPP; return handle_vf_guid(dev, ivt, IFLA_VF_IB_PORT_GUID); } return err; }

Contributors

PersonTokensPropCommitsCommitProp
daniel borkmanndaniel borkmann16024.69%112.50%
chris wrightchris wright14822.84%112.50%
eli coheneli cohen8613.27%112.50%
sucheta chakrabortysucheta chakraborty8312.81%112.50%
hiroshi shimamotohiroshi shimamoto599.10%112.50%
greg rosegreg rose385.86%112.50%
rony efraimrony efraim385.86%112.50%
vladislav zolotarovvladislav zolotarov365.56%112.50%
Total648100.00%8100.00%


static int do_set_master(struct net_device *dev, int ifindex) { struct net_device *upper_dev = netdev_master_upper_dev_get(dev); const struct net_device_ops *ops; int err; if (upper_dev) { if (upper_dev->ifindex == ifindex) return 0; ops = upper_dev->netdev_ops; if (ops->ndo_del_slave) { err = ops->ndo_del_slave(upper_dev, dev); if (err) return err; } else { return -EOPNOTSUPP; } } if (ifindex) { upper_dev = __dev_get_by_index(dev_net(dev), ifindex); if (!upper_dev) return -EINVAL; ops = upper_dev->netdev_ops; if (ops->ndo_add_slave) { err = ops->ndo_add_slave(upper_dev, dev); if (err) return err; } else { return -EOPNOTSUPP; } } return 0; }

Contributors

PersonTokensPropCommitsCommitProp
jiri pirkojiri pirko158100.00%2100.00%
Total158100.00%2100.00%

#define DO_SETLINK_MODIFIED 0x01 /* notify flag means notify + modified. */ #define DO_SETLINK_NOTIFY 0x03
static int do_setlink(const struct sk_buff *skb, struct net_device *dev, struct ifinfomsg *ifm, struct nlattr **tb, char *ifname, int status) { const struct net_device_ops *ops = dev->netdev_ops; int err; if (tb[IFLA_NET_NS_PID] || tb[IFLA_NET_NS_FD]) { struct net *net = rtnl_link_get_net(dev_net(dev), tb); if (IS_ERR(net)) { err = PTR_ERR(net); goto errout; } if (!netlink_ns_capable(skb, net->user_ns, CAP_NET_ADMIN)) { put_net(net); err = -EPERM; goto errout; } err = dev_change_net_namespace(dev, net, ifname); put_net(net); if (err) goto errout; status |= DO_SETLINK_MODIFIED; } if (tb[IFLA_MAP]) { struct rtnl_link_ifmap *u_map; struct ifmap k_map; if (!ops->ndo_set_config) { err = -EOPNOTSUPP; goto errout; } if (!netif_device_present(dev)) { err = -ENODEV; goto errout; } u_map = nla_data(tb[IFLA_MAP]); k_map.mem_start = (unsigned long) u_map->mem_start; k_map.mem_end = (unsigned long) u_map->mem_end; k_map.base_addr = (unsigned short) u_map->base_addr; k_map.irq = (unsigned char) u_map->irq; k_map.dma = (unsigned char) u_map->dma; k_map.port = (unsigned char) u_map->port; err = ops->ndo_set_config(dev, &k_map); if (err < 0) goto errout; status |= DO_SETLINK_NOTIFY; } if (tb[IFLA_ADDRESS]) { struct sockaddr *sa; int len; len = sizeof(sa_family_t) + dev->addr_len; sa = kmalloc(len, GFP_KERNEL); if (!sa) { err = -ENOMEM; goto errout; } sa->sa_family = dev->type; memcpy(sa->sa_data, nla_data(tb[IFLA_ADDRESS]), dev->addr_len); err = dev_set_mac_address(dev, sa); kfree(sa); if (err) goto errout; status |= DO_SETLINK_MODIFIED; } if (tb[IFLA_MTU]) { err = dev_set_mtu(dev, nla_get_u32(tb[IFLA_MTU])); if (err < 0) goto errout; status |= DO_SETLINK_MODIFIED; } if (tb[IFLA_GROUP]) { dev_set_group(dev, nla_get_u32(tb[IFLA_GROUP])); status |= DO_SETLINK_NOTIFY; } /* * Interface selected by interface index but interface * name provided implies that a name change has been * requested. */ if (ifm->ifi_index > 0 && ifname[0]) { err = dev_change_name(dev, ifname); if (err < 0) goto errout; status |= DO_SETLINK_MODIFIED; } if (tb[IFLA_IFALIAS]) { err = dev_set_alias(dev, nla_data(tb[IFLA_IFALIAS]), nla_len(tb[IFLA_IFALIAS])); if (err < 0) goto errout; status |= DO_SETLINK_NOTIFY; } if (tb[IFLA_BROADCAST]) { nla_memcpy(dev->broadcast, tb[IFLA_BROADCAST], dev->addr_len); call_netdevice_notifiers(NETDEV_CHANGEADDR, dev); } if (ifm->ifi_flags || ifm->ifi_change) { err = dev_change_flags(dev, rtnl_dev_combine_flags(dev, ifm)); if (err < 0) goto errout; } if (tb[IFLA_MASTER]) { err = do_set_master(dev, nla_get_u32(tb[IFLA_MASTER])); if (err) goto errout; status |= DO_SETLINK_MODIFIED; } if (tb[IFLA_CARRIER]) { err = dev_change_carrier(dev, nla_get_u8(tb[IFLA_CARRIER])); if (err) goto errout; status |= DO_SETLINK_MODIFIED; } if (tb[IFLA_TXQLEN]) { unsigned long value = nla_get_u32(tb[IFLA_TXQLEN]); unsigned long orig_len = dev->tx_queue_len; if (dev->tx_queue_len ^ value) { dev->tx_queue_len = value; err = call_netdevice_notifiers( NETDEV_CHANGE_TX_QUEUE_LEN, dev); err = notifier_to_errno(err); if (err) { dev->tx_queue_len = orig_len; goto errout; } status |= DO_SETLINK_NOTIFY; } } if (tb[IFLA_OPERSTATE]) set_operstate(dev, nla_get_u8(tb[IFLA_OPERSTATE])); if (tb[IFLA_LINKMODE]) { unsigned char value = nla_get_u8(tb[IFLA_LINKMODE]); write_lock_bh(&dev_base_lock); if (dev->link_mode ^ value) status |= DO_SETLINK_NOTIFY; dev->link_mode = value; write_unlock_bh(&dev_base_lock); } if (tb[IFLA_VFINFO_LIST]) { struct nlattr *vfinfo[IFLA_VF_MAX + 1]; struct nlattr *attr; int rem; nla_for_each_nested(attr, tb[IFLA_VFINFO_LIST], rem) { if (nla_type(attr) != IFLA_VF_INFO || nla_len(attr) < NLA_HDRLEN) { err = -EINVAL; goto errout; } err = nla_parse_nested(vfinfo, IFLA_VF_MAX, attr, ifla_vf_policy); if (err < 0) goto errout; err = do_setvfinfo(dev, vfinfo); if (err < 0) goto errout; status |= DO_SETLINK_NOTIFY; } } err = 0; if (tb[IFLA_VF_PORTS]) { struct nlattr *port[IFLA_PORT_MAX+1]; struct nlattr *attr; int vf; int rem; err = -EOPNOTSUPP; if (!ops->ndo_set_vf_port) goto errout; nla_for_each_nested(attr, tb[IFLA_VF_PORTS], rem) { if (nla_type(attr) != IFLA_VF_PORT || nla_len(attr) < NLA_HDRLEN) { err = -EINVAL; goto errout; } err = nla_parse_nested(port, IFLA_PORT_MAX, attr, ifla_port_policy); if (err < 0) goto errout; if (!port[IFLA_PORT_VF]) { err = -EOPNOTSUPP; goto errout; } vf = nla_get_u32(port[IFLA_PORT_VF]); err = ops->ndo_set_vf_port(dev, vf, port); if (err < 0) goto errout; status |= DO_SETLINK_NOTIFY; } } err = 0; if (tb[IFLA_PORT_SELF]) { struct nlattr *port[IFLA_PORT_MAX+1]; err = nla_parse_nested(port, IFLA_PORT_MAX, tb[IFLA_PORT_SELF], ifla_port_policy); if (err < 0) goto errout; err = -EOPNOTSUPP; if (ops->ndo_set_vf_port) err = ops->ndo_set_vf_port(dev, PORT_SELF_VF, port); if (err < 0) goto errout; status |= DO_SETLINK_NOTIFY; } if (tb[IFLA_AF_SPEC]) { struct nlattr *af; int rem; nla_for_each_nested(af, tb[IFLA_AF_SPEC], rem) { const struct rtnl_af_ops *af_ops; if (!(af_ops = rtnl_af_lookup(nla_type(af)))) BUG(); err = af_ops->set_link_af(dev, af); if (err < 0) goto errout; status |= DO_SETLINK_NOTIFY; } } err = 0; if (tb[IFLA_PROTO_DOWN]) { err = dev_change_proto_down(dev, nla_get_u8(tb[IFLA_PROTO_DOWN])); if (err) goto errout; status |= DO_SETLINK_NOTIFY; } if (tb[IFLA_XDP]) { struct nlattr *xdp[IFLA_XDP_MAX + 1]; err = nla_parse_nested(xdp, IFLA_XDP_MAX, tb[IFLA_XDP], ifla_xdp_policy); if (err < 0) goto errout; if (xdp[IFLA_XDP_ATTACHED]) { err = -EINVAL; goto errout; } if (xdp[IFLA_XDP_FD]) { err = dev_change_xdp_fd(dev, nla_get_s32(xdp[IFLA_XDP_FD])); if (err) goto errout; status |= DO_SETLINK_NOTIFY; } } errout: if (status & DO_SETLINK_MODIFIED) { if (status & DO_SETLINK_NOTIFY) netdev_state_change(dev); if (err < 0) net_warn_ratelimited("A link change request failed with some changes committed already. Interface %s may have been left with an inconsistent configuration, please check.\n", dev->name); } return err; }

Contributors

PersonTokensPropCommitsCommitProp
patrick mchardypatrick mchardy43730.10%37.32%
scott feldmanscott feldman22315.36%12.44%
nicolas dichtelnicolas dichtel1137.78%512.20%
eric w. biedermaneric w. biederman1027.02%512.20%
brenden blancobrenden blanco966.61%24.88%
thomas grafthomas graf845.79%49.76%
jiri pirkojiri pirko714.89%37.32%
daniel borkmanndaniel borkmann573.93%24.88%
stephen hemmingerstephen hemminger563.86%24.88%
jason wangjason wang453.10%12.44%
mitch a williamsmitch a williams412.82%24.88%
anuradha karuppiahanuradha karuppiah352.41%12.44%
pre-gitpre-git231.58%24.88%
dogaru vladdogaru vlad231.58%12.44%
chris wrightchris wright161.10%12.44%
johannes bergjohannes berg110.76%12.44%
stefan rompfstefan rompf80.55%12.44%
david howellsdavid howells70.48%12.44%
joe perchesjoe perches20.14%12.44%
jamal hadi salimjamal hadi salim10.07%12.44%
david s. millerdavid s. miller10.07%12.44%
Total1452100.00%41100.00%


static int rtnl_setlink(struct sk_buff *skb, struct nlmsghdr *nlh) { struct net *net = sock_net(skb->sk); struct ifinfomsg *ifm; struct net_device *dev; int err; struct nlattr *tb[IFLA_MAX+1]; char ifname[IFNAMSIZ]; err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFLA_MAX, ifla_policy); if (err < 0) goto errout; if (tb[IFLA_IFNAME]) nla_strlcpy(ifname, tb[IFLA_IFNAME], IFNAMSIZ); else ifname[0] = '\0'; err = -EINVAL; ifm = nlmsg_data(nlh); if (ifm->ifi_index > 0) dev = __dev_get_by_index(net, ifm->ifi_index); else if (tb[IFLA_IFNAME]) dev = __dev_get_by_name(net, ifname); else goto errout; if (dev == NULL) { err = -ENODEV; goto errout; } err = validate_linkmsg(dev, tb); if (err < 0) goto errout; err = do_setlink(skb, dev, ifm, tb, ifname, 0); errout: return err; }

Contributors

PersonTokensPropCommitsCommitProp
patrick mchardypatrick mchardy12757.73%17.14%
pre-gitpre-git3315.00%428.57%
thomas grafthomas graf2812.73%214.29%
eric w. biedermaneric w. biederman156.82%214.29%
eric dumazeteric dumazet73.18%214.29%
pavel emelianovpavel emelianov41.82%17.14%
alexey kuznetsovalexey kuznetsov31.36%17.14%
hideaki yoshifujihideaki yoshifuji31.36%17.14%
Total220100.00%14100.00%


static int rtnl_group_dellink(const struct net *net, int group) { struct net_device *dev, *aux; LIST_HEAD(list_kill); bool found = false; if (!group) return -EPERM; for_each_netdev(net, dev) { if (dev->group == group) { const struct rtnl_link_ops *ops; found = true; ops = dev->rtnl_link_ops; if (!ops || !ops->dellink) return -EOPNOTSUPP; } } if (!found) return -ENODEV; for_each_netdev_safe(net, dev, aux) { if (dev->group == group) { const struct rtnl_link_ops *ops; ops = dev->rtnl_link_ops; ops->dellink(dev, &list_kill); } } unregister_netdevice_many(&list_kill); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
americo wangamerico wang150100.00%1100.00%
Total150100.00%1100.00%


int rtnl_delete_link(struct net_device *dev) { const struct rtnl_link_ops *ops; LIST_HEAD(list_kill); ops = dev->rtnl_link_ops; if (!ops || !ops->dellink) return -EOPNOTSUPP; ops->dellink(dev, &list_kill); unregister_netdevice_many(&list_kill); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
thomas grafthomas graf60100.00%1100.00%
Total60100.00%1100.00%

EXPORT_SYMBOL_GPL(rtnl_delete_link);
static int rtnl_dellink(struct sk_buff *skb, struct nlmsghdr *nlh) { struct net *net = sock_net(skb->sk); struct net_device *dev; struct ifinfomsg *ifm; char ifname[IFNAMSIZ]; struct nlattr *tb[IFLA_MAX+1]; int err; err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFLA_MAX, ifla_policy); if (err < 0) return err; if (tb[IFLA_IFNAME]) nla_strlcpy(ifname, tb[IFLA_IFNAME], IFNAMSIZ); ifm = nlmsg_data(nlh); if (ifm->ifi_index > 0) dev = __dev_get_by_index(net, ifm->ifi_index); else if (tb[IFLA_IFNAME]) dev = __dev_get_by_name(net, ifname); else if (tb[IFLA_GROUP]) return rtnl_group_dellink(net, nla_get_u32(tb[IFLA_GROUP])); else return -EINVAL; if (!dev) return -ENODEV; return rtnl_delete_link(dev); }

Contributors

PersonTokensPropCommitsCommitProp
patrick mchardypatrick mchardy13269.84%114.29%
americo wangamerico wang2211.64%114.29%
thomas grafthomas graf189.52%228.57%
eric w. biedermaneric w. biederman136.88%114.29%
hideaki yoshifujihideaki yoshifuji31.59%114.29%
eric dumazeteric dumazet10.53%114.29%
Total189100.00%7100.00%


int rtnl_configure_link(struct net_device *dev, const struct ifinfomsg *ifm) { unsigned int old_flags; int err; old_flags = dev->flags; if (ifm && (ifm->ifi_flags || ifm->ifi_change)) { err = __dev_change_flags(dev, rtnl_dev_combine_flags(dev, ifm)); if (err < 0) return err; } dev->rtnl_link_state = RTNL_LINK_INITIALIZED; __dev_notify_flags(dev, old_flags, ~0U); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
patrick mchardypatrick mchardy8496.55%150.00%
nicolas dichtelnicolas dichtel33.45%150.00%
Total87100.00%2100.00%

EXPORT_SYMBOL(rtnl_configure_link);
struct net_device *rtnl_create_link(struct net *net, const char *ifname, unsigned char name_assign_type, const struct rtnl_link_ops *ops, struct nlattr *tb[]) { int err; struct net_device *dev; unsigned int num_tx_queues = 1; unsigned int num_rx_queues = 1; if (tb[IFLA_NUM_TX_QUEUES]) num_tx_queues = nla_get_u32(tb[IFLA_NUM_TX_QUEUES]); else if (ops->get_num_tx_queues) num_tx_queues = ops->get_num_tx_queues(); if (tb[IFLA_NUM_RX_QUEUES]) num_rx_queues = nla_get_u32(tb[IFLA_NUM_RX_QUEUES]); else if (ops->get_num_rx_queues) num_rx_queues = ops->get_num_rx_queues(); err = -ENOMEM; dev = alloc_netdev_mqs(ops->priv_size, ifname, name_assign_type, ops->setup, num_tx_queues, num_rx_queues); if (!dev) goto err; dev_net_set(dev, net); dev->rtnl_link_ops = ops; dev->rtnl_link_state = RTNL_LINK_INITIALIZING; if (tb[IFLA_MTU]) dev->mtu = nla_get_u32(tb[IFLA_MTU]); if (tb[IFLA_ADDRESS]) { memcpy(dev->dev_addr, nla_data(tb[IFLA_ADDRESS]), nla_len(tb[IFLA_ADDRESS])); dev->addr_assign_type = NET_ADDR_SET; } if (tb[IFLA_BROADCAST]) memcpy(dev->broadcast, nla_data(tb[IFLA_BROADCAST]), nla_len(tb[IFLA_BROADCAST])); if (tb[IFLA_TXQLEN]) dev->tx_queue_len = nla_get_u32(tb[IFLA_TXQLEN]); if (tb[IFLA_OPERSTATE]) set_operstate(dev, nla_get_u8(tb[IFLA_OPERSTATE])); if (tb[IFLA_LINKMODE]) dev->link_mode = nla_get_u8(tb[IFLA_LINKMODE]); if (tb[IFLA_GROUP]) dev_set_group(dev, nla_get_u32(tb[IFLA_GROUP])); return dev; err: return ERR_PTR(err); }

Contributors

PersonTokensPropCommitsCommitProp
pavel emelianovpavel emelianov20659.88%17.69%
jiri pirkojiri pirko6719.48%323.08%
patrick mchardypatrick mchardy246.98%215.38%
eric dumazeteric dumazet205.81%17.69%
eric w. biedermaneric w. biederman185.23%215.38%
tom gundersentom gundersen61.74%215.38%
stephen hemmingerstephen hemminger20.58%17.69%
thomas grafthomas graf10.29%17.69%
Total344100.00%13100.00%

EXPORT_SYMBOL(rtnl_create_link);
static int rtnl_group_changelink(const struct sk_buff *skb, struct net *net, int group, struct ifinfomsg *ifm, struct nlattr **tb) { struct net_device *dev, *aux; int err; for_each_netdev_safe(net, dev, aux) { if (dev->group == group) { err = do_setlink(skb, dev, ifm, tb, NULL, 0); if (err < 0) return err; } } return 0; }

Contributors

PersonTokensPropCommitsCommitProp
dogaru vladdogaru vlad7784.62%133.33%
eric w. biedermaneric w. biederman88.79%133.33%
americo wangamerico wang66.59%133.33%
Total91100.00%3100.00%


static int rtnl_newlink(struct sk_buff *skb, struct nlmsghdr *nlh) { struct net *net = sock_net(skb->sk); const struct rtnl_link_ops *ops; const struct rtnl_link_ops *m_ops = NULL; struct net_device *dev; struct net_device *master_dev = NULL; struct ifinfomsg *ifm; char kind[MODULE_NAME_LEN]; char ifname[IFNAMSIZ]; struct nlattr *tb[IFLA_MAX+1]; struct nlattr *linkinfo[IFLA_INFO_MAX+1]; unsigned char name_assign_type = NET_NAME_USER; int err; #ifdef CONFIG_MODULES replay: #endif err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFLA_MAX, ifla_policy); if (err < 0) return err; if (tb[IFLA_IFNAME]) nla_strlcpy(ifname, tb[IFLA_IFNAME], IFNAMSIZ); else ifname[0] = '\0'; ifm = nlmsg_data(nlh); if (ifm->ifi_index > 0) dev = __dev_get_by_index(net, ifm->ifi_index); else { if (ifname[0]) dev = __dev_get_by_name(net, ifname); else dev = NULL; } if (dev) { master_dev = netdev_master_upper_dev_get(dev); if (master_dev) m_ops = master_dev->rtnl_link_ops; } err = validate_linkmsg(dev, tb); if (err < 0) return err; if (tb[IFLA_LINKINFO]) { err = nla_parse_nested(linkinfo, IFLA_INFO_MAX, tb[IFLA_LINKINFO], ifla_info_policy); if (err < 0) return err; } else memset(linkinfo, 0, sizeof(linkinfo)); if (linkinfo[IFLA_INFO_KIND]) { nla_strlcpy(kind, linkinfo[IFLA_INFO_KIND], sizeof(kind)); ops = rtnl_link_ops_get(kind); } else { kind[0] = '\0'; ops = NULL; } if (1) { struct nlattr *attr[ops ? ops->maxtype + 1 : 1]; struct nlattr *slave_attr[m_ops ? m_ops->slave_maxtype + 1 : 1]; struct nlattr **data = NULL; struct nlattr **slave_data = NULL; struct net *dest_net, *link_net = NULL; if (ops) { if (ops->maxtype && linkinfo[IFLA_INFO_DATA]) { err = nla_parse_nested(attr, ops->maxtype, linkinfo[IFLA_INFO_DATA], ops->policy); if (err < 0) return err; data = attr; } if (ops->validate) { err = ops->validate(tb, data); if (err < 0) return err; } } if (m_ops) { if (m_ops->slave_maxtype && linkinfo[IFLA_INFO_SLAVE_DATA]) { err = nla_parse_nested(slave_attr, m_ops->slave_maxtype, linkinfo[IFLA_INFO_SLAVE_DATA], m_ops->slave_policy); if (err < 0) return err; slave_data = slave_attr; } if (m_ops->slave_validate) { err = m_ops->slave_validate(tb, slave_data); if (err < 0) return err; } } if (dev) { int status = 0; if (nlh->nlmsg_flags & NLM_F_EXCL) return -EEXIST; if (nlh->nlmsg_flags & NLM_F_REPLACE) return -EOPNOTSUPP; if (linkinfo[IFLA_INFO_DATA]) { if (!ops || ops != dev->rtnl_link_ops || !ops->changelink) return -EOPNOTSUPP; err = ops->changelink(dev, tb, data); if (err < 0) return err; status |= DO_SETLINK_NOTIFY; } if (linkinfo[IFLA_INFO_SLAVE_DATA]) { if (!m_ops || !m_ops->slave_changelink) return -EOPNOTSUPP; err = m_ops->slave_changelink(master_dev, dev, tb, slave_data); if (err < 0) return err; status |= DO_SETLINK_NOTIFY; } return do_setlink(skb, dev, ifm, tb, ifname, status); } if (!(nlh->nlmsg_flags & NLM_F_CREATE)) { if (ifm->ifi_index == 0 && tb[IFLA_GROUP]) return rtnl_group_changelink(skb, net, nla_get_u32(tb[IFLA_GROUP]), ifm, tb); return -ENODEV; } if (tb[IFLA_MAP] || tb[IFLA_MASTER] || tb[IFLA_PROTINFO]) return -EOPNOTSUPP; if (!ops) { #ifdef CONFIG_MODULES if (kind[0]) { __rtnl_unlock(); request_module("rtnl-link-%s", kind); rtnl_lock(); ops = rtnl_link_ops_get(kind); if (ops) goto replay; } #endif return -EOPNOTSUPP; } if (!ops->setup) return -EOPNOTSUPP; if (!ifname[0]) { snprintf(ifname, IFNAMSIZ, "%s%%d", ops->kind); name_assign_type = NET_NAME_ENUM; } dest_net = rtnl_link_get_net(net, tb); if (IS_ERR(dest_net)) return PTR_ERR(dest_net); err = -EPERM; if (!netlink_ns_capable(skb, dest_net->user_ns, CAP_NET_ADMIN)) goto out; if (tb[IFLA_LINK_NETNSID]) { int id = nla_get_s32(tb[IFLA_LINK_NETNSID]); link_net = get_net_ns_by_id(dest_net, id); if (!link_net) { err = -EINVAL; goto out; } err = -EPERM; if (!netlink_ns_capable(skb, link_net->user_ns, CAP_NET_ADMIN)) goto out; } dev = rtnl_create_link(link_net ? : dest_net, ifname, name_assign_type, ops, tb); if (IS_ERR(dev)) { err = PTR_ERR(dev); goto out; } dev->ifindex = ifm->ifi_index; if (ops->newlink) { err = ops->newlink(link_net ? : net, dev, tb, data); /* Drivers should call free_netdev() in ->destructor * and unregister it on failure after registration * so that device could be finally freed in rtnl_unlock. */ if (err < 0) { /* If device is not registered at all, free it now */ if (dev->reg_state == NETREG_UNINITIALIZED) free_netdev(dev); goto out; } } else { err = register_netdevice(dev); if (err < 0) { free_netdev(dev); goto out; } } err = rtnl_configure_link(dev, ifm); if (err < 0) goto out_unregister; if (link_net) { err = dev_change_net_namespace(dev, dest_net, ifname); if (err < 0) goto out_unregister; } out: if (link_net) put_net(link_net); put_net(dest_net); return err; out_unregister: if (ops->newlink) { LIST_HEAD(list_kill); ops->dellink(dev, &list_kill); unregister_netdevice_many(&list_kill); } else { unregister_netdevice(dev); } goto out; } }

Contributors

PersonTokensPropCommitsCommitProp
patrick mchardypatrick mchardy52242.61%715.91%
jiri pirkojiri pirko20316.57%24.55%
thomas grafthomas graf1078.73%715.91%
nicolas dichtelnicolas dichtel977.92%511.36%
eric w. biedermaneric w. biederman977.92%613.64%
david s. millerdavid s. miller625.06%24.55%
roland dreierroland dreier494.00%24.55%
cong wangcong wang302.45%24.55%
pavel emelianovpavel emelianov171.39%24.55%
tom gundersentom gundersen141.14%12.27%
stefan rompfstefan rompf80.65%12.27%
eric dumazeteric dumazet40.33%12.27%
eric lemoineeric lemoine30.24%12.27%
hideaki yoshifujihideaki yoshifuji30.24%12.27%
dogaru vladdogaru vlad30.24%12.27%
sasha levinsasha levin20.16%12.27%
johannes bergjohannes berg20.16%12.27%
dan carpenterdan carpenter20.16%12.27%
Total1225100.00%44100.00%


static int rtnl_getlink(struct sk_buff *skb, struct nlmsghdr* nlh) { struct net *net = sock_net(skb->sk); struct ifinfomsg *ifm; char ifname[IFNAMSIZ]; struct nlattr *tb[IFLA_MAX+1]; struct net_device *dev = NULL; struct sk_buff *nskb; int err; u32 ext_filter_mask = 0; err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFLA_MAX, ifla_policy); if (err < 0) return err; if (tb[IFLA_IFNAME]) nla_strlcpy(ifname, tb[IFLA_IFNAME], IFNAMSIZ); if (tb[IFLA_EXT_MASK]) ext_filter_mask = nla_get_u32(tb[IFLA_EXT_MASK]); ifm = nlmsg_data(nlh); if (ifm->ifi_index > 0) dev = __dev_get_by_index(net, ifm->ifi_index); else if (tb[IFLA_IFNAME]) dev = __dev_get_by_name(net, ifname); else return -EINVAL; if (dev == NULL) return -ENODEV; nskb = nlmsg_new(if_nlmsg_size(dev, ext_filter_mask), GFP_KERNEL); if (nskb == NULL) return -ENOBUFS; err = rtnl_fill_ifinfo(nskb, dev, RTM_NEWLINK, NETLINK_CB(skb).portid, nlh->nlmsg_seq, 0, 0, ext_filter_mask); if (err < 0) { /* -EMSGSIZE implies BUG in if_nlmsg_size */ WARN_ON(err == -EMSGSIZE); kfree_skb(nskb); } else err = rtnl_unicast(nskb, net, NETLINK_CB(skb).portid); return err; }

Contributors

PersonTokensPropCommitsCommitProp
jean tourrilhesjean tourrilhes8931.23%16.67%
thomas grafthomas graf7626.67%320.00%
eric dumazeteric dumazet5117.89%16.67%
greg rosegreg rose269.12%16.67%
patrick mchardypatrick mchardy227.72%426.67%
eric w. biedermaneric w. biederman134.56%213.33%
hideaki yoshifujihideaki yoshifuji31.05%16.67%
eric sesterhenneric sesterhenn31.05%16.67%
denis v. lunevdenis v. lunev20.70%16.67%
Total285100.00%15100.00%


static u16 rtnl_calcit(struct sk_buff *skb, struct nlmsghdr *nlh) { struct net *net = sock_net(skb->sk); struct net_device *dev; struct nlattr *tb[IFLA_MAX+1]; u32 ext_filter_mask = 0; u16 min_ifinfo_dump_size = 0; int hdrlen; /* Same kernel<->userspace interface hack as in rtnl_dump_ifinfo. */ hdrlen = nlmsg_len(nlh) < sizeof(struct ifinfomsg) ? sizeof(struct rtgenmsg) : sizeof(struct ifinfomsg); if (nlmsg_parse(nlh, hdrlen, tb, IFLA_MAX, ifla_policy) >= 0) { if (tb[IFLA_EXT_MASK]) ext_filter_mask = nla_get_u32(tb[IFLA_EXT_MASK]); } if (!ext_filter_mask) return NLMSG_GOODSIZE; /* * traverse the list of net devices and compute the minimum * buffer size based upon the filter mask. */ list_for_each_entry(dev, &net->dev_base_head, dev_list) { min_ifinfo_dump_size = max_t(u16, min_ifinfo_dump_size, if_nlmsg_size(dev, ext_filter_mask)); } return min_ifinfo_dump_size; }

Contributors

PersonTokensPropCommitsCommitProp
greg rosegreg rose12177.56%240.00%
michal schmidtmichal schmidt2918.59%120.00%
eric dumazeteric dumazet53.21%120.00%
michael rieschmichael riesch10.64%120.00%
Total156100.00%5100.00%


static int rtnl_dump_all(struct sk_buff *skb, struct netlink_callback *cb) { int idx; int s_idx = cb->family; if (s_idx == 0) s_idx = 1; for (idx = 1; idx <= RTNL_FAMILY_MAX; idx++) { int type = cb->nlh->nlmsg_type-RTM_BASE; if (idx < s_idx || idx == PF_PACKET) continue; if (rtnl_msg_handlers[idx] == NULL || rtnl_msg_handlers[idx][type].dumpit == NULL) continue; if (idx > s_idx) { memset(&cb->args[0], 0, sizeof(cb->args)); cb->prev_seq = 0; cb->seq = 0; } if (rtnl_msg_handlers[idx][type].dumpit(skb, cb)) break; } cb->family = idx; return skb->len; }

Contributors

PersonTokensPropCommitsCommitProp
pre-gitpre-git14387.20%228.57%
nicolas dichtelnicolas dichtel148.54%114.29%
thomas grafthomas graf42.44%228.57%
patrick mchardypatrick mchardy21.22%114.29%
adrian bunkadrian bunk10.61%114.29%
Total164100.00%7100.00%


struct sk_buff *rtmsg_ifinfo_build_skb(int type, struct net_device *dev, unsigned int change, gfp_t flags) { struct net *net = dev_net(dev); struct sk_buff *skb; int err = -ENOBUFS; size_t if_info_size; skb = nlmsg_new((if_info_size = if_nlmsg_size(dev, 0)), flags); if (skb == NULL) goto errout; err = rtnl_fill_ifinfo(skb, dev, type, 0, 0, change, 0, 0); if (err < 0) { /* -EMSGSIZE implies BUG in if_nlmsg_size() */ WARN_ON(err == -EMSGSIZE); kfree_skb(skb); goto errout; } return skb; errout: if (err < 0) rtnl_set_sk_err(net, RTNLGRP_LINK, err); return NULL; }

Contributors

PersonTokensPropCommitsCommitProp
pre-gitpre-git4733.10%526.32%
mahesh bandewarmahesh bandewar2819.72%15.26%
patrick mchardypatrick mchardy2316.20%210.53%
thomas grafthomas graf1510.56%315.79%
greg rosegreg rose117.75%210.53%
eric w. biedermaneric w. biederman74.93%15.26%
alexei starovoitovalexei starovoitov42.82%15.26%
hideaki yoshifujihideaki yoshifuji32.11%15.26%
jamal hadi salimjamal hadi salim21.41%15.26%
eric dumazeteric dumazet10.70%15.26%
alexey kuznetsovalexey kuznetsov10.70%15.26%
Total142100.00%19100.00%


void rtmsg_ifinfo_send(struct sk_buff *skb, struct net_device *dev, gfp_t flags) { struct net *net = dev_net(dev); rtnl_notify(skb, net, 0, RTNLGRP_LINK, NULL, flags); }

Contributors

PersonTokensPropCommitsCommitProp
mahesh bandewarmahesh bandewar2865.12%114.29%
pre-gitpre-git818.60%114.29%
thomas grafthomas graf36.98%114.29%
alexei starovoitovalexei starovoitov12.33%114.29%
denis v. lunevdenis v. lunev12.33%114.29%
eric w. biedermaneric w. biederman12.33%114.29%
patrick mchardypatrick mchardy12.33%114.29%
Total43100.00%7100.00%


void rtmsg_ifinfo(int type, struct net_device *dev, unsigned int change, gfp_t flags) { struct sk_buff *skb; if (dev->reg_state != NETREG_REGISTERED) return; skb = rtmsg_ifinfo_build_skb(type, dev, change, flags); if (skb) rtmsg_ifinfo_send(skb, dev, flags); }

Contributors

PersonTokensPropCommitsCommitProp
mahesh bandewarmahesh bandewar4270.00%120.00%
nicolas dichtelnicolas dichtel915.00%120.00%
thomas grafthomas graf711.67%120.00%
pre-gitpre-git11.67%120.00%
denis v. lunevdenis v. lunev11.67%120.00%
Total60100.00%5100.00%

EXPORT_SYMBOL(rtmsg_ifinfo);
static int nlmsg_populate_fdb_fill(struct sk_buff *skb, struct net_device *dev, u8 *addr, u16 vid, u32 pid, u32 seq, int type, unsigned int flags, int nlflags, u16 ndm_state) { struct nlmsghdr *nlh; struct ndmsg *ndm; nlh = nlmsg_put(skb, pid, seq, type, sizeof(*ndm), nlflags); if (!nlh) return -EMSGSIZE; ndm = nlmsg_data(nlh); ndm->ndm_family = AF_BRIDGE; ndm->ndm_pad1 = 0; ndm->ndm_pad2 = 0; ndm->ndm_flags = flags; ndm->ndm_type = 0; ndm->ndm_ifindex = dev->ifindex; ndm->ndm_state = ndm_state; if (nla_put(skb, NDA_LLADDR, ETH_ALEN, addr)) goto nla_put_failure; if (vid) if (nla_put(skb, NDA_VLAN, sizeof(u16), &vid)) goto nla_put_failure; nlmsg_end(skb, nlh); return 0; nla_put_failure: nlmsg_cancel(skb, nlh); return -EMSGSIZE; }

Contributors

PersonTokensPropCommitsCommitProp
john fastabendjohn fastabend15880.61%120.00%
hubert sokolowskihubert sokolowski3115.82%240.00%
nicolas dichtelnicolas dichtel42.04%120.00%
johannes bergjohannes berg31.53%120.00%
Total196100.00%5100.00%


static inline size_t rtnl_fdb_nlmsg_size(void) { return NLMSG_ALIGN(sizeof(struct ndmsg)) + nla_total_size(ETH_ALEN); }

Contributors

PersonTokensPropCommitsCommitProp
john fastabendjohn fastabend24100.00%1100.00%
Total24100.00%1100.00%


static void rtnl_fdb_notify(struct net_device *dev, u8 *addr, u16 vid, int type, u16 ndm_state) { struct net *net = dev_net(dev); struct sk_buff *skb; int err = -ENOBUFS; skb = nlmsg_new(rtnl_fdb_nlmsg_size(), GFP_ATOMIC); if (!skb) goto errout; err = nlmsg_populate_fdb_fill(skb, dev, addr, vid, 0, 0, type, NTF_SELF, 0, ndm_state); if (err < 0) { kfree_skb(skb); goto errout; } rtnl_notify(skb, net, 0, RTNLGRP_NEIGH, NULL, GFP_ATOMIC); return; errout: rtnl_set_sk_err(net, RTNLGRP_NEIGH, err); }

Contributors

PersonTokensPropCommitsCommitProp
john fastabendjohn fastabend11990.84%125.00%
hubert sokolowskihubert sokolowski107.63%250.00%
nicolas dichtelnicolas dichtel21.53%125.00%
Total131100.00%4100.00%

/** * ndo_dflt_fdb_add - default netdevice operation to add an FDB entry */
int ndo_dflt_fdb_add(struct ndmsg *ndm, struct nlattr *tb[], struct net_device *dev, const unsigned char *addr, u16 vid, u16 flags) { int err = -EINVAL; /* If aging addresses are supported device will need to * implement its own handler for this. */ if (ndm->ndm_state && !(ndm->ndm_state & NUD_PERMANENT)) { pr_info("%s: FDB only supports static addresses\n", dev->name); return err; } if (vid) { pr_info("%s: vlans aren't supported yet for dev_uc|mc_add()\n", dev->name); return err; } if (is_unicast_ether_addr(addr) || is_link_local_ether_addr(addr)) err = dev_uc_add_excl(dev, addr); else if (is_multicast_ether_addr(addr)) err = dev_mc_add_excl(dev, addr); /* Only return duplicate errors if NLM_F_EXCL is set */ if (err == -EEXIST && !(flags & NLM_F_EXCL)) err = 0; return err; }

Contributors

PersonTokensPropCommitsCommitProp
vlad yasevichvlad yasevich12685.71%133.33%
or gerlitzor gerlitz1812.24%133.33%
jiri pirkojiri pirko32.04%133.33%
Total147100.00%3100.00%

EXPORT_SYMBOL(ndo_dflt_fdb_add);
static int fdb_vid_parse(struct nlattr *vlan_attr, u16 *p_vid) { u16 vid = 0; if (vlan_attr) { if (nla_len(vlan_attr) != sizeof(u16)) { pr_info("PF_BRIDGE: RTM_NEWNEIGH with invalid vlan\n"); return -EINVAL; } vid = nla_get_u16(vlan_attr); if (!vid || vid >= VLAN_VID_MASK) { pr_info("PF_BRIDGE: RTM_NEWNEIGH with invalid vlan id %d\n", vid); return -EINVAL; } } *p_vid = vid; return 0; }

Contributors

PersonTokensPropCommitsCommitProp
jiri pirkojiri pirko7486.05%120.00%
pre-gitpre-git89.30%120.00%
hideaki yoshifujihideaki yoshifuji22.33%120.00%
linus torvaldslinus torvalds11.16%120.00%
denis v. lunevdenis v. lunev11.16%120.00%
Total86100.00%5100.00%


static int rtnl_fdb_add(struct sk_buff *skb, struct nlmsghdr *nlh) { struct net *net = sock_net(skb->sk); struct ndmsg *ndm; struct nlattr *tb[NDA_MAX+1]; struct net_device *dev; u8 *addr; u16 vid; int err; err = nlmsg_parse(nlh, sizeof(*ndm), tb, NDA_MAX, NULL); if (err < 0) return err; ndm = nlmsg_data(nlh); if (ndm->ndm_ifindex == 0) { pr_info("PF_BRIDGE: RTM_NEWNEIGH with invalid ifindex\n"); return -EINVAL; } dev = __dev_get_by_index(net, ndm->ndm_ifindex); if (dev == NULL) { pr_info("PF_BRIDGE: RTM_NEWNEIGH with unknown ifindex\n"); return -ENODEV; } if (!tb[NDA_LLADDR] || nla_len(tb[NDA_LLADDR]) != ETH_ALEN) { pr_info("PF_BRIDGE: RTM_NEWNEIGH with invalid address\n"); return -EINVAL; } addr = nla_data(tb[NDA_LLADDR]); err = fdb_vid_parse(tb[NDA_VLAN], &vid); if (err) return err; err = -EOPNOTSUPP; /* Support fdb on master device the net/bridge default case */ if ((!ndm->ndm_flags || ndm->ndm_flags & NTF_MASTER) && (dev->priv_flags & IFF_BRIDGE_PORT)) { struct net_device *br_dev = netdev_master_upper_dev_get(dev); const struct net_device_ops *ops = br_dev->netdev_ops; err = ops->ndo_fdb_add(ndm, tb, dev, addr, vid, nlh->nlmsg_flags); if (err) goto out; else ndm->ndm_flags &= ~NTF_MASTER; } /* Embedded bridge, macvlan, and any other device support */ if ((ndm->ndm_flags & NTF_SELF)) { if (dev->netdev_ops->ndo_fdb_add) err = dev->netdev_ops->ndo_fdb_add(ndm, tb, dev, addr, vid, nlh->nlmsg_flags); else err = ndo_dflt_fdb_add(ndm, tb, dev, addr, vid, nlh->nlmsg_flags); if (!err) { rtnl_fdb_notify(dev, addr, vid, RTM_NEWNEIGH, ndm->ndm_state); ndm->ndm_flags &= ~NTF_SELF; } } out: return err; }

Contributors

PersonTokensPropCommitsCommitProp
john fastabendjohn fastabend22959.64%211.76%
jiri pirkojiri pirko4812.50%211.76%
pre-gitpre-git4712.24%211.76%
vlad yasevichvlad yasevich225.73%15.88%
denis v. lunevdenis v. lunev102.60%15.88%
thomas grafthomas graf71.82%211.76%
hubert sokolowskihubert sokolowski61.56%211.76%
stephen hemmingerstephen hemminger41.04%15.88%
greg rosegreg rose41.04%15.88%
eric dumazeteric dumazet30.78%15.88%
hideaki yoshifujihideaki yoshifuji30.78%15.88%
linus torvaldslinus torvalds10.26%15.88%
Total384100.00%17100.00%

/** * ndo_dflt_fdb_del - default netdevice operation to delete an FDB entry */
int ndo_dflt_fdb_del(struct ndmsg *ndm, struct nlattr *tb[], struct net_device *dev, const unsigned char *addr, u16 vid) { int err = -EINVAL; /* If aging addresses are supported device will need to * implement its own handler for this. */ if (!(ndm->ndm_state & NUD_PERMANENT)) { pr_info("%s: FDB only supports static addresses\n", dev->name); return err; } if (is_unicast_ether_addr(addr) || is_link_local_ether_addr(addr)) err = dev_uc_del(dev, addr); else if (is_multicast_ether_addr(addr)) err = dev_mc_del(dev, addr); return err; }

Contributors

PersonTokensPropCommitsCommitProp
vlad yasevichvlad yasevich9592.23%125.00%
sridhar samudralasridhar samudrala32.91%125.00%
jiri pirkojiri pirko32.91%125.00%
alexander duyckalexander duyck21.94%125.00%
Total103100.00%4100.00%

EXPORT_SYMBOL(ndo_dflt_fdb_del);
static int rtnl_fdb_del(struct sk_buff *skb, struct nlmsghdr *nlh) { struct net *net = sock_net(skb->sk); struct ndmsg *ndm; struct nlattr *tb[NDA_MAX+1]; struct net_device *dev; int err = -EINVAL; __u8 *addr; u16 vid; if (!netlink_capable(skb, CAP_NET_ADMIN)) return -EPERM; err = nlmsg_parse(nlh, sizeof(*ndm), tb, NDA_MAX, NULL); if (err < 0) return err; ndm = nlmsg_data(nlh); if (ndm->ndm_ifindex == 0) { pr_info("PF_BRIDGE: RTM_DELNEIGH with invalid ifindex\n"); return -EINVAL; } dev = __dev_get_by_index(net, ndm->ndm_ifindex); if (dev == NULL) { pr_info("PF_BRIDGE: RTM_DELNEIGH with unknown ifindex\n"); return -ENODEV; } if (!tb[NDA_LLADDR] || nla_len(tb[NDA_LLADDR]) != ETH_ALEN) { pr_info("PF_BRIDGE: RTM_DELNEIGH with invalid address\n"); return -EINVAL; } addr = nla_data(tb[NDA_LLADDR]); err = fdb_vid_parse(tb[NDA_VLAN], &vid); if (err) return err; err = -EOPNOTSUPP; /* Support fdb on master device the net/bridge default case */ if ((!ndm->ndm_flags || ndm->ndm_flags & NTF_MASTER) && (dev->priv_flags & IFF_BRIDGE_PORT)) { struct net_device *br_dev = netdev_master_upper_dev_get(dev); const struct net_device_ops *ops = br_dev->netdev_ops; if (ops->ndo_fdb_del) err = ops->ndo_fdb_del(ndm, tb, dev, addr, vid); if (err) goto out; else ndm->ndm_flags &= ~NTF_MASTER; } /* Embedded bridge, macvlan, and any other device support */ if (ndm->ndm_flags & NTF_SELF) { if (dev->netdev_ops->ndo_fdb_del) err = dev->netdev_ops->ndo_fdb_del(ndm, tb, dev, addr, vid); else err = ndo_dflt_fdb_del(ndm, tb, dev, addr, vid); if (!err) { rtnl_fdb_notify(dev, addr, vid, RTM_DELNEIGH, ndm->ndm_state); ndm->ndm_flags &= ~NTF_SELF; } } out: return err; }

Contributors

PersonTokensPropCommitsCommitProp
john fastabendjohn fastabend27168.96%222.22%
vlad yasevichvlad yasevich6917.56%222.22%
jiri pirkojiri pirko4411.20%222.22%
hubert sokolowskihubert sokolowski61.53%222.22%
eric w. biedermaneric w. biederman30.76%111.11%
Total393100.00%9100.00%


static int nlmsg_populate_fdb(struct sk_buff *skb, struct netlink_callback *cb, struct net_device *dev, int *idx, struct netdev_hw_addr_list *list) { struct netdev_hw_addr *ha; int err; u32 portid, seq; portid = NETLINK_CB(cb->skb).portid; seq = cb->nlh->nlmsg_seq; list_for_each_entry(ha, &list->list, list) { if (*idx < cb->args[0]) goto skip; err = nlmsg_populate_fdb_fill(skb, dev, ha->addr, 0, portid, seq, RTM_NEWNEIGH, NTF_SELF, NLM_F_MULTI, NUD_PERMANENT); if (err < 0) return err; skip: *idx += 1; } return 0; }

Contributors

PersonTokensPropCommitsCommitProp
john fastabendjohn fastabend12392.48%233.33%
hubert sokolowskihubert sokolowski43.01%233.33%
eric w. biedermaneric w. biederman43.01%116.67%
nicolas dichtelnicolas dichtel21.50%116.67%
Total133100.00%6100.00%

/** * ndo_dflt_fdb_dump - default netdevice operation to dump an FDB table. * @nlh: netlink message header * @dev: netdevice * * Default netdevice operation to dump the existing unicast address list. * Returns number of addresses from list put in skb. */
int ndo_dflt_fdb_dump(struct sk_buff *skb, struct netlink_callback *cb, struct net_device *dev, struct net_device *filter_dev, int idx) { int err; netif_addr_lock_bh(dev); err = nlmsg_populate_fdb(skb, cb, dev, &idx, &dev->uc); if (err) goto out; nlmsg_populate_fdb(skb, cb, dev, &idx, &dev->mc); out: netif_addr_unlock_bh(dev); cb->args[1] = err; return idx; }

Contributors

PersonTokensPropCommitsCommitProp
john fastabendjohn fastabend8485.71%133.33%
makoto minouramakoto minoura99.18%133.33%
jamal hadi salimjamal hadi salim55.10%133.33%
Total98100.00%3100.00%

EXPORT_SYMBOL(ndo_dflt_fdb_dump);
static int rtnl_fdb_dump(struct sk_buff *skb, struct netlink_callback *cb) { struct net_device *dev; struct nlattr *tb[IFLA_MAX+1]; struct net_device *br_dev = NULL; const struct net_device_ops *ops = NULL; const struct net_device_ops *cops = NULL; struct ifinfomsg *ifm = nlmsg_data(cb->nlh); struct net *net = sock_net(skb->sk); int brport_idx = 0; int br_idx = 0; int idx = 0; if (nlmsg_parse(cb->nlh, sizeof(struct ifinfomsg), tb, IFLA_MAX, ifla_policy) == 0) { if (tb[IFLA_MASTER]) br_idx = nla_get_u32(tb[IFLA_MASTER]); } brport_idx = ifm->ifi_index; if (br_idx) { br_dev = __dev_get_by_index(net, br_idx); if (!br_dev) return -ENODEV; ops = br_dev->netdev_ops; } cb->args[1] = 0; for_each_netdev(net, dev) { if (brport_idx && (dev->ifindex != brport_idx)) continue; if (!br_idx) { /* user did not specify a specific bridge */ if (dev->priv_flags & IFF_BRIDGE_PORT) { br_dev = netdev_master_upper_dev_get(dev); cops = br_dev->netdev_ops; } } else { if (dev != br_dev && !(dev->priv_flags & IFF_BRIDGE_PORT)) continue; if (br_dev != netdev_master_upper_dev_get(dev) && !(dev->priv_flags & IFF_EBRIDGE)) continue; cops = ops; } if (dev->priv_flags & IFF_BRIDGE_PORT) { if (cops && cops->ndo_fdb_dump) idx = cops->ndo_fdb_dump(skb, cb, br_dev, dev, idx); } if (cb->args[1] == -EMSGSIZE) break; if (dev->netdev_ops->ndo_fdb_dump) idx = dev->netdev_ops->ndo_fdb_dump(skb, cb, dev, NULL, idx); else idx = ndo_dflt_fdb_dump(skb, cb, dev, NULL, idx); if (cb->args[1] == -EMSGSIZE) break; cops = NULL; } cb->args[0] = idx; return skb->len; }

Contributors

PersonTokensPropCommitsCommitProp
jamal hadi salimjamal hadi salim23058.08%225.00%
john fastabendjohn fastabend10326.01%225.00%
makoto minouramakoto minoura358.84%112.50%
hubert sokolowskihubert sokolowski174.29%112.50%
jiri pirkojiri pirko102.53%112.50%
vlad yasevichvlad yasevich10.25%112.50%
Total396100.00%8100.00%


static int brport_nla_put_flag(struct sk_buff *skb, u32 flags, u32 mask, unsigned int attrnum, unsigned int flag) { if (mask & flag) return nla_put_u8(skb, attrnum, !!(flags & flag)); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
scott feldmanscott feldman50100.00%1100.00%
Total50100.00%1100.00%


int ndo_dflt_bridge_getlink(struct sk_buff *skb, u32 pid, u32 seq, struct net_device *dev, u16 mode, u32 flags, u32 mask, int nlflags, u32 filter_mask, int (*vlan_fill)(struct sk_buff *skb, struct net_device *dev, u32 filter_mask)) { struct nlmsghdr *nlh; struct ifinfomsg *ifm; struct nlattr *br_afspec; struct nlattr *protinfo; u8 operstate = netif_running(dev) ? dev->operstate : IF_OPER_DOWN; struct net_device *br_dev = netdev_master_upper_dev_get(dev); int err = 0; nlh = nlmsg_put(skb, pid, seq, RTM_NEWLINK, sizeof(*ifm), nlflags); if (nlh == NULL) return -EMSGSIZE; ifm = nlmsg_data(nlh); ifm->ifi_family = AF_BRIDGE; ifm->__ifi_pad = 0; ifm->ifi_type = dev->type; ifm->ifi_index = dev->ifindex; ifm->ifi_flags = dev_get_flags(dev); ifm->ifi_change = 0; if (nla_put_string(skb, IFLA_IFNAME, dev->name) || nla_put_u32(skb, IFLA_MTU, dev->mtu) || nla_put_u8(skb, IFLA_OPERSTATE, operstate) || (br_dev && nla_put_u32(skb, IFLA_MASTER, br_dev->ifindex)) || (dev->addr_len && nla_put(skb, IFLA_ADDRESS, dev->addr_len, dev->dev_addr)) || (dev->ifindex != dev_get_iflink(dev) && nla_put_u32(skb, IFLA_LINK, dev_get_iflink(dev)))) goto nla_put_failure; br_afspec = nla_nest_start(skb, IFLA_AF_SPEC); if (!br_afspec) goto nla_put_failure; if (nla_put_u16(skb, IFLA_BRIDGE_FLAGS, BRIDGE_FLAGS_SELF)) { nla_nest_cancel(skb, br_afspec); goto nla_put_failure; } if (mode != BRIDGE_MODE_UNDEF) { if (nla_put_u16(skb, IFLA_BRIDGE_MODE, mode)) { nla_nest_cancel(skb, br_afspec); goto nla_put_failure; } } if (vlan_fill) { err = vlan_fill(skb, dev, filter_mask); if (err) { nla_nest_cancel(skb, br_afspec); goto nla_put_failure; } } nla_nest_end(skb, br_afspec); protinfo = nla_nest_start(skb, IFLA_PROTINFO | NLA_F_NESTED); if (!protinfo) goto nla_put_failure; if (brport_nla_put_flag(skb, flags, mask, IFLA_BRPORT_MODE, BR_HAIRPIN_MODE) || brport_nla_put_flag(skb, flags, mask, IFLA_BRPORT_GUARD, BR_BPDU_GUARD) || brport_nla_put_flag(skb, flags, mask, IFLA_BRPORT_FAST_LEAVE, BR_MULTICAST_FAST_LEAVE) || brport_nla_put_flag(skb, flags, mask, IFLA_BRPORT_PROTECT, BR_ROOT_BLOCK) || brport_nla_put_flag(skb, flags, mask, IFLA_BRPORT_LEARNING, BR_LEARNING) || brport_nla_put_flag(skb, flags, mask, IFLA_BRPORT_LEARNING_SYNC, BR_LEARNING_SYNC) || brport_nla_put_flag(skb, flags, mask, IFLA_BRPORT_UNICAST_FLOOD, BR_FLOOD) || brport_nla_put_flag(skb, flags, mask, IFLA_BRPORT_PROXYARP, BR_PROXYARP)) { nla_nest_cancel(skb, protinfo); goto nla_put_failure; } nla_nest_end(skb, protinfo); nlmsg_end(skb, nlh); return 0; nla_put_failure: nlmsg_cancel(skb, nlh); return err ? err : -EMSGSIZE; }

Contributors

PersonTokensPropCommitsCommitProp
john fastabendjohn fastabend29552.40%112.50%
scott feldmanscott feldman22039.08%225.00%
roopa prabhuroopa prabhu234.09%112.50%
jiri pirkojiri pirko122.13%112.50%
nicolas dichtelnicolas dichtel101.78%225.00%
johannes bergjohannes berg30.53%112.50%
Total563100.00%8100.00%

EXPORT_SYMBOL_GPL(ndo_dflt_bridge_getlink);
static int rtnl_bridge_getlink(struct sk_buff *skb, struct netlink_callback *cb) { struct net *net = sock_net(skb->sk); struct net_device *dev; int idx = 0; u32 portid = NETLINK_CB(cb->skb).portid; u32 seq = cb->nlh->nlmsg_seq; u32 filter_mask = 0; int err; if (nlmsg_len(cb->nlh) > sizeof(struct ifinfomsg)) { struct nlattr *extfilt; extfilt = nlmsg_find_attr(cb->nlh, sizeof(struct ifinfomsg), IFLA_EXT_MASK); if (extfilt) { if (nla_len(extfilt) < sizeof(filter_mask)) return -EINVAL; filter_mask = nla_get_u32(extfilt); } } rcu_read_lock(); for_each_netdev_rcu(net, dev) { const struct net_device_ops *ops = dev->netdev_ops; struct net_device *br_dev = netdev_master_upper_dev_get(dev); if (br_dev && br_dev->netdev_ops->ndo_bridge_getlink) { if (idx >= cb->args[0]) { err = br_dev->netdev_ops->ndo_bridge_getlink( skb, portid, seq, dev, filter_mask, NLM_F_MULTI); if (err < 0 && err != -EOPNOTSUPP) break; } idx++; } if (ops->ndo_bridge_getlink) { if (idx >= cb->args[0]) { err = ops->ndo_bridge_getlink(skb, portid, seq, dev, filter_mask, NLM_F_MULTI); if (err < 0 && err != -EOPNOTSUPP) break; } idx++; } } rcu_read_unlock(); cb->args[0] = idx; return skb->len; }

Contributors

PersonTokensPropCommitsCommitProp
john fastabendjohn fastabend16053.51%112.50%
thomas grafthomas graf4013.38%112.50%
vlad yasevichvlad yasevich3612.04%112.50%
roopa prabhuroopa prabhu3110.37%112.50%
ben hutchingsben hutchings206.69%112.50%
jiri pirkojiri pirko72.34%112.50%
nicolas dichtelnicolas dichtel41.34%112.50%
asbjoern sloth toennesenasbjoern sloth toennesen10.33%112.50%
Total299100.00%8100.00%


static inline size_t bridge_nlmsg_size(void) { return NLMSG_ALIGN(sizeof(struct ifinfomsg)) + nla_total_size(IFNAMSIZ) /* IFLA_IFNAME */ + nla_total_size(MAX_ADDR_LEN) /* IFLA_ADDRESS */ + nla_total_size(sizeof(u32)) /* IFLA_MASTER */ + nla_total_size(sizeof(u32)) /* IFLA_MTU */ + nla_total_size(sizeof(u32)) /* IFLA_LINK */ + nla_total_size(sizeof(u32)) /* IFLA_OPERSTATE */ + nla_total_size(sizeof(u8)) /* IFLA_PROTINFO */ + nla_total_size(sizeof(struct nlattr)) /* IFLA_AF_SPEC */ + nla_total_size(sizeof(u16)) /* IFLA_BRIDGE_FLAGS */ + nla_total_size(sizeof(u16)); /* IFLA_BRIDGE_MODE */ }

Contributors

PersonTokensPropCommitsCommitProp
john fastabendjohn fastabend104100.00%1100.00%
Total104100.00%1100.00%


static int rtnl_bridge_notify(struct net_device *dev) { struct net *net = dev_net(dev); struct sk_buff *skb; int err = -EOPNOTSUPP; if (!dev->netdev_ops->ndo_bridge_getlink) return 0; skb = nlmsg_new(bridge_nlmsg_size(), GFP_ATOMIC); if (!skb) { err = -ENOMEM; goto errout; } err = dev->netdev_ops->ndo_bridge_getlink(skb, 0, 0, dev, 0, 0); if (err < 0) goto errout; if (!skb->len) goto errout; rtnl_notify(skb, net, 0, RTNLGRP_LINK, NULL, GFP_ATOMIC); return 0; errout: WARN_ON(err == -EMSGSIZE); kfree_skb(skb); if (err) rtnl_set_sk_err(net, RTNLGRP_LINK, err); return err; }

Contributors

PersonTokensPropCommitsCommitProp
john fastabendjohn fastabend12881.01%120.00%
roopa prabhuroopa prabhu2616.46%240.00%
vlad yasevichvlad yasevich21.27%120.00%
nicolas dichtelnicolas dichtel21.27%120.00%
Total158100.00%5100.00%


static int rtnl_bridge_setlink(struct sk_buff *skb, struct nlmsghdr *nlh) { struct net *net = sock_net(skb->sk); struct ifinfomsg *ifm; struct net_device *dev; struct nlattr *br_spec, *attr = NULL; int rem, err = -EOPNOTSUPP; u16 flags = 0; bool have_flags = false; if (nlmsg_len(nlh) < sizeof(*ifm)) return -EINVAL; ifm = nlmsg_data(nlh); if (ifm->ifi_family != AF_BRIDGE) return -EPFNOSUPPORT; dev = __dev_get_by_index(net, ifm->ifi_index); if (!dev) { pr_info("PF_BRIDGE: RTM_SETLINK with unknown ifindex\n"); return -ENODEV; } br_spec = nlmsg_find_attr(nlh, sizeof(struct ifinfomsg), IFLA_AF_SPEC); if (br_spec) { nla_for_each_nested(attr, br_spec, rem) { if (nla_type(attr) == IFLA_BRIDGE_FLAGS) { if (nla_len(attr) < sizeof(flags)) return -EINVAL; have_flags = true; flags = nla_get_u16(attr); break; } } } if (!flags || (flags & BRIDGE_FLAGS_MASTER)) { struct net_device *br_dev = netdev_master_upper_dev_get(dev); if (!br_dev || !br_dev->netdev_ops->ndo_bridge_setlink) { err = -EOPNOTSUPP; goto out; } err = br_dev->netdev_ops->ndo_bridge_setlink(dev, nlh, flags); if (err) goto out; flags &= ~BRIDGE_FLAGS_MASTER; } if ((flags & BRIDGE_FLAGS_SELF)) { if (!dev->netdev_ops->ndo_bridge_setlink) err = -EOPNOTSUPP; else err = dev->netdev_ops->ndo_bridge_setlink(dev, nlh, flags); if (!err) { flags &= ~BRIDGE_FLAGS_SELF; /* Generate event to notify upper layer of bridge * change */ err = rtnl_bridge_notify(dev); } } if (have_flags) memcpy(nla_data(attr), &flags, sizeof(flags)); out: return err; }

Contributors

PersonTokensPropCommitsCommitProp
john fastabendjohn fastabend31387.92%342.86%
thomas grafthomas graf164.49%114.29%
roopa prabhuroopa prabhu143.93%228.57%
jiri pirkojiri pirko133.65%114.29%
Total356100.00%7100.00%


static int rtnl_bridge_dellink(struct sk_buff *skb, struct nlmsghdr *nlh) { struct net *net = sock_net(skb->sk); struct ifinfomsg *ifm; struct net_device *dev; struct nlattr *br_spec, *attr = NULL; int rem, err = -EOPNOTSUPP; u16 flags = 0; bool have_flags = false; if (nlmsg_len(nlh) < sizeof(*ifm)) return -EINVAL; ifm = nlmsg_data(nlh); if (ifm->ifi_family != AF_BRIDGE) return -EPFNOSUPPORT; dev = __dev_get_by_index(net, ifm->ifi_index); if (!dev) { pr_info("PF_BRIDGE: RTM_SETLINK with unknown ifindex\n"); return -ENODEV; } br_spec = nlmsg_find_attr(nlh, sizeof(struct ifinfomsg), IFLA_AF_SPEC); if (br_spec) { nla_for_each_nested(attr, br_spec, rem) { if (nla_type(attr) == IFLA_BRIDGE_FLAGS) { if (nla_len(attr) < sizeof(flags)) return -EINVAL; have_flags = true; flags = nla_get_u16(attr); break; } } } if (!flags || (flags & BRIDGE_FLAGS_MASTER)) { struct net_device *br_dev = netdev_master_upper_dev_get(dev); if (!br_dev || !br_dev->netdev_ops->ndo_bridge_dellink) { err = -EOPNOTSUPP; goto out; } err = br_dev->netdev_ops->ndo_bridge_dellink(dev, nlh, flags); if (err) goto out; flags &= ~BRIDGE_FLAGS_MASTER; } if ((flags & BRIDGE_FLAGS_SELF)) { if (!dev->netdev_ops->ndo_bridge_dellink) err = -EOPNOTSUPP; else err = dev->netdev_ops->ndo_bridge_dellink(dev, nlh, flags); if (!err) { flags &= ~BRIDGE_FLAGS_SELF; /* Generate event to notify upper layer of bridge * change */ err = rtnl_bridge_notify(dev); } } if (have_flags) memcpy(nla_data(attr), &flags, sizeof(flags)); out: return err; }

Contributors

PersonTokensPropCommitsCommitProp
vlad yasevichvlad yasevich32691.57%125.00%
thomas grafthomas graf164.49%125.00%
roopa prabhuroopa prabhu143.93%250.00%
Total356100.00%4100.00%


static bool stats_attr_valid(unsigned int mask, int attrid, int idxattr) { return (mask & IFLA_STATS_FILTER_BIT(attrid)) && (!idxattr || idxattr == attrid); }

Contributors

PersonTokensPropCommitsCommitProp
nikolay aleksandrovnikolay aleksandrov35100.00%1100.00%
Total35100.00%1100.00%


static int rtnl_fill_statsinfo(struct sk_buff *skb, struct net_device *dev, int type, u32 pid, u32 seq, u32 change, unsigned int flags, unsigned int filter_mask, int *idxattr, int *prividx) { struct if_stats_msg *ifsm; struct nlmsghdr *nlh; struct nlattr *attr; int s_prividx = *prividx; ASSERT_RTNL(); nlh = nlmsg_put(skb, pid, seq, type, sizeof(*ifsm), flags); if (!nlh) return -EMSGSIZE; ifsm = nlmsg_data(nlh); ifsm->ifindex = dev->ifindex; ifsm->filter_mask = filter_mask; if (stats_attr_valid(filter_mask, IFLA_STATS_LINK_64, *idxattr)) { struct rtnl_link_stats64 *sp; attr = nla_reserve_64bit(skb, IFLA_STATS_LINK_64, sizeof(struct rtnl_link_stats64), IFLA_STATS_UNSPEC); if (!attr) goto nla_put_failure; sp = nla_data(attr); dev_get_stats(dev, sp); } if (stats_attr_valid(filter_mask, IFLA_STATS_LINK_XSTATS, *idxattr)) { const struct rtnl_link_ops *ops = dev->rtnl_link_ops; if (ops && ops->fill_linkxstats) { int err; *idxattr = IFLA_STATS_LINK_XSTATS; attr = nla_nest_start(skb, IFLA_STATS_LINK_XSTATS); if (!attr) goto nla_put_failure; err = ops->fill_linkxstats(skb, dev, prividx, *idxattr); nla_nest_end(skb, attr); if (err) goto nla_put_failure; *idxattr = 0; } } if (stats_attr_valid(filter_mask, IFLA_STATS_LINK_XSTATS_SLAVE, *idxattr)) { const struct rtnl_link_ops *ops = NULL; const struct net_device *master; master = netdev_master_upper_dev_get(dev); if (master) ops = master->rtnl_link_ops; if (ops && ops->fill_linkxstats) { int err; *idxattr = IFLA_STATS_LINK_XSTATS_SLAVE; attr = nla_nest_start(skb, IFLA_STATS_LINK_XSTATS_SLAVE); if (!attr) goto nla_put_failure; err = ops->fill_linkxstats(skb, dev, prividx, *idxattr); nla_nest_end(skb, attr); if (err) goto nla_put_failure; *idxattr = 0; } } nlmsg_end(skb, nlh); return 0; nla_put_failure: /* not a multi message or no progress mean a real error */ if (!(flags & NLM_F_MULTI) || s_prividx == *prividx) nlmsg_cancel(skb, nlh); else nlmsg_end(skb, nlh); return -EMSGSIZE; }

Contributors

PersonTokensPropCommitsCommitProp
nikolay aleksandrovnikolay aleksandrov25258.33%360.00%
roopa prabhuroopa prabhu17740.97%120.00%
nicolas dichtelnicolas dichtel30.69%120.00%
Total432100.00%5100.00%

static const struct nla_policy ifla_stats_policy[IFLA_STATS_MAX + 1] = { [IFLA_STATS_LINK_64] = { .len = sizeof(struct rtnl_link_stats64) }, };
static size_t if_nlmsg_stats_size(const struct net_device *dev, u32 filter_mask) { size_t size = 0; if (stats_attr_valid(filter_mask, IFLA_STATS_LINK_64, 0)) size += nla_total_size_64bit(sizeof(struct rtnl_link_stats64)); if (stats_attr_valid(filter_mask, IFLA_STATS_LINK_XSTATS, 0)) { const struct rtnl_link_ops *ops = dev->rtnl_link_ops; int attr = IFLA_STATS_LINK_XSTATS; if (ops && ops->get_linkxstats_size) { size += nla_total_size(ops->get_linkxstats_size(dev, attr)); /* for IFLA_STATS_LINK_XSTATS */ size += nla_total_size(0); } } if (stats_attr_valid(filter_mask, IFLA_STATS_LINK_XSTATS_SLAVE, 0)) { struct net_device *_dev = (struct net_device *)dev; const struct rtnl_link_ops *ops = NULL; const struct net_device *master; /* netdev_master_upper_dev_get can't take const */ master = netdev_master_upper_dev_get(_dev); if (master) ops = master->rtnl_link_ops; if (ops && ops->get_linkxstats_size) { int attr = IFLA_STATS_LINK_XSTATS_SLAVE; size += nla_total_size(ops->get_linkxstats_size(dev, attr)); /* for IFLA_STATS_LINK_XSTATS_SLAVE */ size += nla_total_size(0); } } return size; }

Contributors

PersonTokensPropCommitsCommitProp
nikolay aleksandrovnikolay aleksandrov15979.90%375.00%
roopa prabhuroopa prabhu4020.10%125.00%
Total199100.00%4100.00%


static int rtnl_stats_get(struct sk_buff *skb, struct nlmsghdr *nlh) { struct net *net = sock_net(skb->sk); struct net_device *dev = NULL; int idxattr = 0, prividx = 0; struct if_stats_msg *ifsm; struct sk_buff *nskb; u32 filter_mask; int err; ifsm = nlmsg_data(nlh); if (ifsm->ifindex > 0) dev = __dev_get_by_index(net, ifsm->ifindex); else return -EINVAL; if (!dev) return -ENODEV; filter_mask = ifsm->filter_mask; if (!filter_mask) return -EINVAL; nskb = nlmsg_new(if_nlmsg_stats_size(dev, filter_mask), GFP_KERNEL); if (!nskb) return -ENOBUFS; err = rtnl_fill_statsinfo(nskb, dev, RTM_NEWSTATS, NETLINK_CB(skb).portid, nlh->nlmsg_seq, 0, 0, filter_mask, &idxattr, &prividx); if (err < 0) { /* -EMSGSIZE implies BUG in if_nlmsg_stats_size */ WARN_ON(err == -EMSGSIZE); kfree_skb(nskb); } else { err = rtnl_unicast(nskb, net, NETLINK_CB(skb).portid); } return err; }

Contributors

PersonTokensPropCommitsCommitProp
roopa prabhuroopa prabhu19690.74%150.00%
nikolay aleksandrovnikolay aleksandrov209.26%150.00%
Total216100.00%2100.00%


static int rtnl_stats_dump(struct sk_buff *skb, struct netlink_callback *cb) { int h, s_h, err, s_idx, s_idxattr, s_prividx; struct net *net = sock_net(skb->sk); unsigned int flags = NLM_F_MULTI; struct if_stats_msg *ifsm; struct hlist_head *head; struct net_device *dev; u32 filter_mask = 0; int idx = 0; s_h = cb->args[0]; s_idx = cb->args[1]; s_idxattr = cb->args[2]; s_prividx = cb->args[3]; cb->seq = net->dev_base_seq; ifsm = nlmsg_data(cb->nlh); filter_mask = ifsm->filter_mask; if (!filter_mask) return -EINVAL; for (h = s_h; h < NETDEV_HASHENTRIES; h++, s_idx = 0) { idx = 0; head = &net->dev_index_head[h]; hlist_for_each_entry(dev, head, index_hlist) { if (idx < s_idx) goto cont; err = rtnl_fill_statsinfo(skb, dev, RTM_NEWSTATS, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq, 0, flags, filter_mask, &s_idxattr, &s_prividx); /* If we ran out of room on the first message, * we're in trouble */ WARN_ON((err == -EMSGSIZE) && (skb->len == 0)); if (err < 0) goto out; s_prividx = 0; s_idxattr = 0; nl_dump_check_consistent(cb, nlmsg_hdr(skb)); cont: idx++; } } out: cb->args[3] = s_prividx; cb->args[2] = s_idxattr; cb->args[1] = idx; cb->args[0] = h; return skb->len; }

Contributors

PersonTokensPropCommitsCommitProp
roopa prabhuroopa prabhu24976.85%150.00%
nikolay aleksandrovnikolay aleksandrov7523.15%150.00%
Total324100.00%2100.00%

/* Process one rtnetlink message. */
static int rtnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) { struct net *net = sock_net(skb->sk); rtnl_doit_func doit; int kind; int family; int type; int err; type = nlh->nlmsg_type; if (type > RTM_MAX) return -EOPNOTSUPP; type -= RTM_BASE; /* All the messages must have at least 1 byte length */ if (nlmsg_len(nlh) < sizeof(struct rtgenmsg)) return 0; family = ((struct rtgenmsg *)nlmsg_data(nlh))->rtgen_family; kind = type&3; if (kind != 2 && !netlink_net_capable(skb, CAP_NET_ADMIN)) return -EPERM; if (kind == 2 && nlh->nlmsg_flags&NLM_F_DUMP) { struct sock *rtnl; rtnl_dumpit_func dumpit; rtnl_calcit_func calcit; u16 min_dump_alloc = 0; dumpit = rtnl_get_dumpit(family, type); if (dumpit == NULL) return -EOPNOTSUPP; calcit = rtnl_get_calcit(family, type); if (calcit) min_dump_alloc = calcit(skb, nlh); __rtnl_unlock(); rtnl = net->rtnl; { struct netlink_dump_control c = { .dump = dumpit, .min_dump_alloc = min_dump_alloc, }; err = netlink_dump_start(rtnl, skb, nlh, &c); } rtnl_lock(); return err; } doit = rtnl_get_doit(family, type); if (doit == NULL) return -EOPNOTSUPP; return doit(skb, nlh); }

Contributors

PersonTokensPropCommitsCommitProp
john fastabendjohn fastabend19172.08%19.09%
pre-gitpre-git2910.94%218.18%
pablo neira ayusopablo neira ayuso207.55%19.09%
thomas grafthomas graf103.77%327.27%
eric dumazeteric dumazet83.02%19.09%
hong zhi guohong zhi guo41.51%19.09%
eric w. biedermaneric w. biederman31.13%218.18%
Total265100.00%11100.00%


static void rtnetlink_rcv(struct sk_buff *skb) { rtnl_lock(); netlink_rcv_skb(skb, &rtnetlink_rcv_msg); rtnl_unlock(); }

Contributors

PersonTokensPropCommitsCommitProp
pre-gitpre-git1248.00%116.67%
denis v. lunevdenis v. lunev728.00%233.33%
thomas grafthomas graf28.00%116.67%
herbert xuherbert xu28.00%116.67%
david s. millerdavid s. miller28.00%116.67%
Total25100.00%6100.00%


static int rtnetlink_event(struct notifier_block *this, unsigned long event, void *ptr) { struct net_device *dev = netdev_notifier_info_to_dev(ptr); switch (event) { case NETDEV_UP: case NETDEV_DOWN: case NETDEV_PRE_UP: case NETDEV_POST_INIT: case NETDEV_REGISTER: case NETDEV_CHANGE: case NETDEV_PRE_TYPE_CHANGE: case NETDEV_GOING_DOWN: case NETDEV_UNREGISTER: case NETDEV_UNREGISTER_FINAL: case NETDEV_RELEASE: case NETDEV_JOIN: case NETDEV_BONDING_INFO: break; default: rtmsg_ifinfo(RTM_NEWLINK, dev, 0, GFP_KERNEL); break; } return NOTIFY_DONE; }

Contributors

PersonTokensPropCommitsCommitProp
pre-gitpre-git5964.84%325.00%
patrick mchardypatrick mchardy99.89%325.00%
eric w. biedermaneric w. biederman88.79%18.33%
americo wangamerico wang66.59%18.33%
moni shouamoni shoua33.30%18.33%
jiri pirkojiri pirko33.30%18.33%
alexei starovoitovalexei starovoitov22.20%18.33%
eric dumazeteric dumazet11.10%18.33%
Total91100.00%12100.00%

static struct notifier_block rtnetlink_dev_notifier = { .notifier_call = rtnetlink_event, };
static int __net_init rtnetlink_net_init(struct net *net) { struct sock *sk; struct netlink_kernel_cfg cfg = { .groups = RTNLGRP_MAX, .input = rtnetlink_rcv, .cb_mutex = &rtnl_mutex, .flags = NL_CFG_F_NONROOT_RECV, }; sk = netlink_kernel_create(net, NETLINK_ROUTE, &cfg); if (!sk) return -ENOMEM; net->rtnl = sk; return 0; }

Contributors

PersonTokensPropCommitsCommitProp
denis v. lunevdenis v. lunev4459.46%120.00%
pablo neira ayusopablo neira ayuso2837.84%240.00%
alexey dobriyanalexey dobriyan11.35%120.00%
eric dumazeteric dumazet11.35%120.00%
Total74100.00%5100.00%


static void __net_exit rtnetlink_net_exit(struct net *net) { netlink_kernel_release(net->rtnl); net->rtnl = NULL; }

Contributors

PersonTokensPropCommitsCommitProp
denis v. lunevdenis v. lunev2496.00%375.00%
alexey dobriyanalexey dobriyan14.00%125.00%
Total25100.00%4100.00%

static struct pernet_operations rtnetlink_net_ops = { .init = rtnetlink_net_init, .exit = rtnetlink_net_exit, };
void __init rtnetlink_init(void) { if (register_pernet_subsys(&rtnetlink_net_ops)) panic("rtnetlink_init: cannot initialize rtnetlink\n"); register_netdevice_notifier(&rtnetlink_dev_notifier); rtnl_register(PF_UNSPEC, RTM_GETLINK, rtnl_getlink, rtnl_dump_ifinfo, rtnl_calcit); rtnl_register(PF_UNSPEC, RTM_SETLINK, rtnl_setlink, NULL, NULL); rtnl_register(PF_UNSPEC, RTM_NEWLINK, rtnl_newlink, NULL, NULL); rtnl_register(PF_UNSPEC, RTM_DELLINK, rtnl_dellink, NULL, NULL); rtnl_register(PF_UNSPEC, RTM_GETADDR, NULL, rtnl_dump_all, NULL); rtnl_register(PF_UNSPEC, RTM_GETROUTE, NULL, rtnl_dump_all, NULL); rtnl_register(PF_BRIDGE, RTM_NEWNEIGH, rtnl_fdb_add, NULL, NULL); rtnl_register(PF_BRIDGE, RTM_DELNEIGH, rtnl_fdb_del, NULL, NULL); rtnl_register(PF_BRIDGE, RTM_GETNEIGH, NULL, rtnl_fdb_dump, NULL); rtnl_register(PF_BRIDGE, RTM_GETLINK, NULL, rtnl_bridge_getlink, NULL); rtnl_register(PF_BRIDGE, RTM_DELLINK, rtnl_bridge_dellink, NULL, NULL); rtnl_register(PF_BRIDGE, RTM_SETLINK, rtnl_bridge_setlink, NULL, NULL); rtnl_register(PF_UNSPEC, RTM_GETSTATS, rtnl_stats_get, rtnl_stats_dump, NULL); }

Contributors

PersonTokensPropCommitsCommitProp
john fastabendjohn fastabend6533.16%214.29%
thomas grafthomas graf4120.92%214.29%
pre-gitpre-git2512.76%428.57%
patrick mchardypatrick mchardy2211.22%17.14%
roopa prabhuroopa prabhu136.63%17.14%
vlad yasevichvlad yasevich136.63%17.14%
greg rosegreg rose126.12%17.14%
denis v. lunevdenis v. lunev42.04%17.14%
eric w. biedermaneric w. biederman10.51%17.14%
Total196100.00%14100.00%


Overall Contributors

PersonTokensPropCommitsCommitProp
john fastabendjohn fastabend238412.26%92.98%
patrick mchardypatrick mchardy205910.59%185.96%
thomas grafthomas graf203310.46%3411.26%
jiri pirkojiri pirko18229.37%175.63%
scott feldmanscott feldman11996.17%72.32%
hannes frederic sowahannes frederic sowa9584.93%10.33%
roopa prabhuroopa prabhu8254.24%72.32%
pre-gitpre-git7323.76%134.30%
vlad yasevichvlad yasevich7023.61%41.32%
nikolay aleksandrovnikolay aleksandrov5412.78%30.99%
nicolas dichtelnicolas dichtel4002.06%206.62%
eric w. biedermaneric w. biederman3992.05%144.64%
david aherndavid ahern3811.96%20.66%
greg rosegreg rose3791.95%41.32%
eric dumazeteric dumazet3601.85%175.63%
brenden blancobrenden blanco3261.68%20.66%
daniel borkmanndaniel borkmann3221.66%41.32%
chris wrightchris wright3161.63%10.33%
pavel emelianovpavel emelianov2691.38%61.99%
jamal hadi salimjamal hadi salim2381.22%30.99%
eli coheneli cohen2041.05%10.33%
americo wangamerico wang1840.95%30.99%
denis v. lunevdenis v. lunev1670.86%51.66%
stephen hemmingerstephen hemminger1290.66%82.65%
mitch a williamsmitch a williams1290.66%20.66%
eran ben elishaeran ben elisha1230.63%10.33%
stefan rompfstefan rompf1210.62%10.33%
cong wangcong wang1200.62%30.99%
david s. millerdavid s. miller1130.58%113.64%
sucheta chakrabortysucheta chakraborty1100.57%10.33%
dogaru vladdogaru vlad1050.54%20.66%
mahesh bandewarmahesh bandewar980.50%10.33%
hiroshi shimamotohiroshi shimamoto980.50%10.33%
jean tourrilhesjean tourrilhes890.46%10.33%
hubert sokolowskihubert sokolowski740.38%30.99%
vladislav zolotarovvladislav zolotarov730.38%10.33%
michal schmidtmichal schmidt600.31%10.33%
anuradha karuppiahanuradha karuppiah590.30%10.33%
david gibsondavid gibson520.27%20.66%
jiri bencjiri benc510.26%20.66%
pablo neira ayusopablo neira ayuso500.26%41.32%
rony efraimrony efraim490.25%10.33%
roland dreierroland dreier490.25%20.66%
jason wangjason wang450.23%10.33%
makoto minouramakoto minoura440.23%10.33%
li weili wei360.19%10.33%
david decotignydavid decotigny280.14%10.33%
kangjie lukangjie lu260.13%10.33%
johannes bergjohannes berg250.13%41.32%
paul e. mckenneypaul e. mckenney240.12%10.33%
jan engelhardtjan engelhardt210.11%20.66%
ben hutchingsben hutchings210.11%20.66%
peter zijlstrapeter zijlstra200.10%10.33%
hideaki yoshifujihideaki yoshifuji200.10%20.66%
tom gundersentom gundersen200.10%20.66%
ben greearben greear190.10%10.33%
or gerlitzor gerlitz180.09%10.33%
doug ledforddoug ledford130.07%10.33%
mathias krausemathias krause80.04%10.33%
christoph hellwigchristoph hellwig80.04%10.33%
jarod wilsonjarod wilson80.04%10.33%
alexei starovoitovalexei starovoitov70.04%10.33%
david howellsdavid howells70.04%10.33%
arnaldo carvalho de meloarnaldo carvalho de melo70.04%20.66%
ronen aradronen arad70.04%10.33%
alexey kuznetsovalexey kuznetsov50.03%30.99%
ido schimmelido schimmel50.03%10.33%
linus torvaldslinus torvalds50.03%20.66%
hong zhi guohong zhi guo40.02%10.33%
fernando luis vazquez caofernando luis vazquez cao30.02%10.33%
eric lemoineeric lemoine30.02%10.33%
moni shouamoni shoua30.02%10.33%
sridhar samudralasridhar samudrala30.02%10.33%
herbert xuherbert xu30.02%20.66%
eric sesterhenneric sesterhenn30.02%10.33%
james morrisjames morris30.02%10.33%
sowmini varadhansowmini varadhan20.01%10.33%
sasha levinsasha levin20.01%10.33%
adrian bunkadrian bunk20.01%10.33%
alexander duyckalexander duyck20.01%10.33%
joe perchesjoe perches20.01%10.33%
dan carpenterdan carpenter20.01%10.33%
alexey dobriyanalexey dobriyan20.01%10.33%
kurt van dijckkurt van dijck10.01%10.33%
lucas de marchilucas de marchi10.01%10.33%
wei yongjunwei yongjun10.01%10.33%
michael rieschmichael riesch10.01%10.33%
yaowei baiyaowei bai10.01%10.33%
asbjoern sloth toennesenasbjoern sloth toennesen10.01%10.33%
Total19444100.00%302100.00%
Directory: net/core
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.