linux/net/ipv4/devinet.c

// SPDX-License-Identifier: GPL-2.0-or-later
/*
 *	NET3	IP device support routines.
 *
 *	Derived from the IP parts of dev.c 1.0.19
 * 		Authors:	Ross Biro
 *				Fred N. van Kempen, <[email protected]>
 *				Mark Evans, <[email protected]>
 *
 *	Additional Authors:
 *		Alan Cox, <[email protected]>
 *		Alexey Kuznetsov, <[email protected]>
 *
 *	Changes:
 *		Alexey Kuznetsov:	pa_* fields are replaced with ifaddr
 *					lists.
 *		Cyrus Durgin:		updated for kmod
 *		Matthias Andree:	in devinet_ioctl, compare label and
 *					address (4.4BSD alias style support),
 *					fall back to comparing just the label
 *					if no match found.
 */


#include <linux/uaccess.h>
#include <linux/bitops.h>
#include <linux/capability.h>
#include <linux/module.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/sched/signal.h>
#include <linux/string.h>
#include <linux/mm.h>
#include <linux/socket.h>
#include <linux/sockios.h>
#include <linux/in.h>
#include <linux/errno.h>
#include <linux/interrupt.h>
#include <linux/if_addr.h>
#include <linux/if_ether.h>
#include <linux/inet.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/skbuff.h>
#include <linux/init.h>
#include <linux/notifier.h>
#include <linux/inetdevice.h>
#include <linux/igmp.h>
#include <linux/slab.h>
#include <linux/hash.h>
#ifdef CONFIG_SYSCTL
#include <linux/sysctl.h>
#endif
#include <linux/kmod.h>
#include <linux/netconf.h>

#include <net/arp.h>
#include <net/ip.h>
#include <net/route.h>
#include <net/ip_fib.h>
#include <net/rtnetlink.h>
#include <net/net_namespace.h>
#include <net/addrconf.h>

#define IPV6ONLY_FLAGS

static struct ipv4_devconf ipv4_devconf =;

static struct ipv4_devconf ipv4_devconf_dflt =;

#define IPV4_DEVCONF_DFLT(net, attr)

static const struct nla_policy ifa_ipv4_policy[IFA_MAX+1] =;

struct inet_fill_args {};

#define IN4_ADDR_HSIZE_SHIFT
#define IN4_ADDR_HSIZE

static struct hlist_head inet_addr_lst[IN4_ADDR_HSIZE];

static u32 inet_addr_hash(const struct net *net, __be32 addr)
{}

static void inet_hash_insert(struct net *net, struct in_ifaddr *ifa)
{}

static void inet_hash_remove(struct in_ifaddr *ifa)
{}

/**
 * __ip_dev_find - find the first device with a given source address.
 * @net: the net namespace
 * @addr: the source address
 * @devref: if true, take a reference on the found device
 *
 * If a caller uses devref=false, it should be protected by RCU, or RTNL
 */
struct net_device *__ip_dev_find(struct net *net, __be32 addr, bool devref)
{}
EXPORT_SYMBOL();

/* called under RCU lock */
struct in_ifaddr *inet_lookup_ifaddr_rcu(struct net *net, __be32 addr)
{}

static void rtmsg_ifa(int event, struct in_ifaddr *, struct nlmsghdr *, u32);

static BLOCKING_NOTIFIER_HEAD(inetaddr_chain);
static BLOCKING_NOTIFIER_HEAD(inetaddr_validator_chain);
static void inet_del_ifa(struct in_device *in_dev,
			 struct in_ifaddr __rcu **ifap,
			 int destroy);
#ifdef CONFIG_SYSCTL
static int devinet_sysctl_register(struct in_device *idev);
static void devinet_sysctl_unregister(struct in_device *idev);
#else
static int devinet_sysctl_register(struct in_device *idev)
{
	return 0;
}
static void devinet_sysctl_unregister(struct in_device *idev)
{
}
#endif

/* Locks all the inet devices. */

static struct in_ifaddr *inet_alloc_ifa(void)
{}

static void inet_rcu_free_ifa(struct rcu_head *head)
{}

static void inet_free_ifa(struct in_ifaddr *ifa)
{}

static void in_dev_free_rcu(struct rcu_head *head)
{}

void in_dev_finish_destroy(struct in_device *idev)
{}
EXPORT_SYMBOL();

static struct in_device *inetdev_init(struct net_device *dev)
{}

static void inetdev_destroy(struct in_device *in_dev)
{}

int inet_addr_onlink(struct in_device *in_dev, __be32 a, __be32 b)
{}

static void __inet_del_ifa(struct in_device *in_dev,
			   struct in_ifaddr __rcu **ifap,
			   int destroy, struct nlmsghdr *nlh, u32 portid)
{}

static void inet_del_ifa(struct in_device *in_dev,
			 struct in_ifaddr __rcu **ifap,
			 int destroy)
{}

static void check_lifetime(struct work_struct *work);

static DECLARE_DELAYED_WORK(check_lifetime_work, check_lifetime);

static int __inet_insert_ifa(struct in_ifaddr *ifa, struct nlmsghdr *nlh,
			     u32 portid, struct netlink_ext_ack *extack)
{}

static int inet_insert_ifa(struct in_ifaddr *ifa)
{}

static int inet_set_ifa(struct net_device *dev, struct in_ifaddr *ifa)
{}

/* Caller must hold RCU or RTNL :
 * We dont take a reference on found in_device
 */
struct in_device *inetdev_by_index(struct net *net, int ifindex)
{}
EXPORT_SYMBOL();

/* Called only from RTNL semaphored context. No locks. */

struct in_ifaddr *inet_ifa_byprefix(struct in_device *in_dev, __be32 prefix,
				    __be32 mask)
{}

static int ip_mc_autojoin_config(struct net *net, bool join,
				 const struct in_ifaddr *ifa)
{}

static int inet_rtm_deladdr(struct sk_buff *skb, struct nlmsghdr *nlh,
			    struct netlink_ext_ack *extack)
{}

#define INFINITY_LIFE_TIME

static void check_lifetime(struct work_struct *work)
{}

static void set_ifa_lifetime(struct in_ifaddr *ifa, __u32 valid_lft,
			     __u32 prefered_lft)
{}

static struct in_ifaddr *rtm_to_ifaddr(struct net *net, struct nlmsghdr *nlh,
				       __u32 *pvalid_lft, __u32 *pprefered_lft,
				       struct netlink_ext_ack *extack)
{}

static struct in_ifaddr *find_matching_ifa(struct in_ifaddr *ifa)
{}

static int inet_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh,
			    struct netlink_ext_ack *extack)
{}

/*
 *	Determine a default network mask, based on the IP address.
 */

static int inet_abc_len(__be32 addr)
{}


int devinet_ioctl(struct net *net, unsigned int cmd, struct ifreq *ifr)
{}

int inet_gifconf(struct net_device *dev, char __user *buf, int len, int size)
{}

static __be32 in_dev_select_addr(const struct in_device *in_dev,
				 int scope)
{}

__be32 inet_select_addr(const struct net_device *dev, __be32 dst, int scope)
{}
EXPORT_SYMBOL();

static __be32 confirm_addr_indev(struct in_device *in_dev, __be32 dst,
			      __be32 local, int scope)
{}

/*
 * Confirm that local IP address exists using wildcards:
 * - net: netns to check, cannot be NULL
 * - in_dev: only on this interface, NULL=any interface
 * - dst: only in the same subnet as dst, 0=any dst
 * - local: address, 0=autoselect the local address
 * - scope: maximum allowed scope value for the local address
 */
__be32 inet_confirm_addr(struct net *net, struct in_device *in_dev,
			 __be32 dst, __be32 local, int scope)
{}
EXPORT_SYMBOL();

/*
 *	Device notifier
 */

int register_inetaddr_notifier(struct notifier_block *nb)
{}
EXPORT_SYMBOL();

int unregister_inetaddr_notifier(struct notifier_block *nb)
{}
EXPORT_SYMBOL();

int register_inetaddr_validator_notifier(struct notifier_block *nb)
{}
EXPORT_SYMBOL();

int unregister_inetaddr_validator_notifier(struct notifier_block *nb)
{}
EXPORT_SYMBOL();

/* Rename ifa_labels for a device name change. Make some effort to preserve
 * existing alias numbering and to create unique labels if possible.
*/
static void inetdev_changename(struct net_device *dev, struct in_device *in_dev)
{}

static void inetdev_send_gratuitous_arp(struct net_device *dev,
					struct in_device *in_dev)

{}

/* Called only under RTNL semaphore */

static int inetdev_event(struct notifier_block *this, unsigned long event,
			 void *ptr)
{}

static struct notifier_block ip_netdev_notifier =;

static size_t inet_nlmsg_size(void)
{}

static inline u32 cstamp_delta(unsigned long cstamp)
{}

static int put_cacheinfo(struct sk_buff *skb, unsigned long cstamp,
			 unsigned long tstamp, u32 preferred, u32 valid)
{}

static int inet_fill_ifaddr(struct sk_buff *skb, const struct in_ifaddr *ifa,
			    struct inet_fill_args *args)
{}

static int inet_valid_dump_ifaddr_req(const struct nlmsghdr *nlh,
				      struct inet_fill_args *fillargs,
				      struct net **tgt_net, struct sock *sk,
				      struct netlink_callback *cb)
{}

static int in_dev_dump_addr(struct in_device *in_dev, struct sk_buff *skb,
			    struct netlink_callback *cb, int *s_ip_idx,
			    struct inet_fill_args *fillargs)
{}

/* Combine dev_addr_genid and dev_base_seq to detect changes.
 */
static u32 inet_base_seq(const struct net *net)
{}

static int inet_dump_ifaddr(struct sk_buff *skb, struct netlink_callback *cb)
{}

static void rtmsg_ifa(int event, struct in_ifaddr *ifa, struct nlmsghdr *nlh,
		      u32 portid)
{}

static size_t inet_get_link_af_size(const struct net_device *dev,
				    u32 ext_filter_mask)
{}

static int inet_fill_link_af(struct sk_buff *skb, const struct net_device *dev,
			     u32 ext_filter_mask)
{}

static const struct nla_policy inet_af_policy[IFLA_INET_MAX+1] =;

static int inet_validate_link_af(const struct net_device *dev,
				 const struct nlattr *nla,
				 struct netlink_ext_ack *extack)
{}

static int inet_set_link_af(struct net_device *dev, const struct nlattr *nla,
			    struct netlink_ext_ack *extack)
{}

static int inet_netconf_msgsize_devconf(int type)
{}

static int inet_netconf_fill_devconf(struct sk_buff *skb, int ifindex,
				     const struct ipv4_devconf *devconf,
				     u32 portid, u32 seq, int event,
				     unsigned int flags, int type)
{}

void inet_netconf_notify_devconf(struct net *net, int event, int type,
				 int ifindex, struct ipv4_devconf *devconf)
{}

static const struct nla_policy devconf_ipv4_policy[NETCONFA_MAX+1] =;

static int inet_netconf_valid_get_req(struct sk_buff *skb,
				      const struct nlmsghdr *nlh,
				      struct nlattr **tb,
				      struct netlink_ext_ack *extack)
{}

static int inet_netconf_get_devconf(struct sk_buff *in_skb,
				    struct nlmsghdr *nlh,
				    struct netlink_ext_ack *extack)
{}

static int inet_netconf_dump_devconf(struct sk_buff *skb,
				     struct netlink_callback *cb)
{}

#ifdef CONFIG_SYSCTL

static void devinet_copy_dflt_conf(struct net *net, int i)
{}

/* called with RTNL locked */
static void inet_forward_change(struct net *net)
{}

static int devinet_conf_ifindex(struct net *net, struct ipv4_devconf *cnf)
{}

static int devinet_conf_proc(const struct ctl_table *ctl, int write,
			     void *buffer, size_t *lenp, loff_t *ppos)
{}

static int devinet_sysctl_forward(const struct ctl_table *ctl, int write,
				  void *buffer, size_t *lenp, loff_t *ppos)
{}

static int ipv4_doint_and_flush(const struct ctl_table *ctl, int write,
				void *buffer, size_t *lenp, loff_t *ppos)
{}

#define DEVINET_SYSCTL_ENTRY(attr, name, mval, proc)

#define DEVINET_SYSCTL_RW_ENTRY(attr, name)

#define DEVINET_SYSCTL_RO_ENTRY(attr, name)

#define DEVINET_SYSCTL_COMPLEX_ENTRY(attr, name, proc)

#define DEVINET_SYSCTL_FLUSHING_ENTRY(attr, name)

static struct devinet_sysctl_table {} devinet_sysctl =;

static int __devinet_sysctl_register(struct net *net, char *dev_name,
				     int ifindex, struct ipv4_devconf *p)
{}

static void __devinet_sysctl_unregister(struct net *net,
					struct ipv4_devconf *cnf, int ifindex)
{}

static int devinet_sysctl_register(struct in_device *idev)
{}

static void devinet_sysctl_unregister(struct in_device *idev)
{}

static struct ctl_table ctl_forward_entry[] =;
#endif

static __net_init int devinet_init_net(struct net *net)
{}

static __net_exit void devinet_exit_net(struct net *net)
{}

static __net_initdata struct pernet_operations devinet_ops =;

static struct rtnl_af_ops inet_af_ops __read_mostly =;

void __init devinet_init(void)
{}