net/ipv6/addrconf.c

Source file repositories/reference/linux-study-clean/net/ipv6/addrconf.c

File Facts

System
Linux kernel
Corpus path
net/ipv6/addrconf.c
Extension
.c
Size
193481 bytes
Lines
7650
Domain
Networking Core
Bucket
Sockets, Protocols, Packet Path, And Network Policy
Inferred role
Networking Core: exported/initcall integration point
Status
integration implementation candidate

Why This File Exists

Networking stack implementation surface: socket APIs, protocol dispatch, packet flow, routing, filtering, and network namespaces.

Dependency Surface

Detected Declarations

Annotated Snippet

struct ipv6_saddr_score {
	int			rule;
	int			addr_type;
	struct inet6_ifaddr	*ifa;
	DECLARE_BITMAP(scorebits, IPV6_SADDR_RULE_MAX);
	int			scopedist;
	int			matchlen;
};

struct ipv6_saddr_dst {
	const struct in6_addr *addr;
	int ifindex;
	int scope;
	int label;
	unsigned int prefs;
};

static inline int ipv6_saddr_preferred(int type)
{
	if (type & (IPV6_ADDR_MAPPED|IPV6_ADDR_COMPATv4|IPV6_ADDR_LOOPBACK))
		return 1;
	return 0;
}

static bool ipv6_use_optimistic_addr(const struct net *net,
				     const struct inet6_dev *idev)
{
#ifdef CONFIG_IPV6_OPTIMISTIC_DAD
	if (!idev)
		return false;
	if (!READ_ONCE(net->ipv6.devconf_all->optimistic_dad) &&
	    !READ_ONCE(idev->cnf.optimistic_dad))
		return false;
	if (!READ_ONCE(net->ipv6.devconf_all->use_optimistic) &&
	    !READ_ONCE(idev->cnf.use_optimistic))
		return false;

	return true;
#else
	return false;
#endif
}

static bool ipv6_allow_optimistic_dad(const struct net *net,
				      const struct inet6_dev *idev)
{
#ifdef CONFIG_IPV6_OPTIMISTIC_DAD
	if (!idev)
		return false;
	if (!READ_ONCE(net->ipv6.devconf_all->optimistic_dad) &&
	    !READ_ONCE(idev->cnf.optimistic_dad))
		return false;

	return true;
#else
	return false;
#endif
}

static int ipv6_get_saddr_eval(struct net *net,
			       struct ipv6_saddr_score *score,
			       struct ipv6_saddr_dst *dst,
			       int i)
{
	int ret;

	if (i <= score->rule) {
		switch (i) {
		case IPV6_SADDR_RULE_SCOPE:
			ret = score->scopedist;
			break;
		case IPV6_SADDR_RULE_PREFIX:
			ret = score->matchlen;
			break;
		default:
			ret = !!test_bit(i, score->scorebits);
		}
		goto out;
	}

	switch (i) {
	case IPV6_SADDR_RULE_INIT:
		/* Rule 0: remember if hiscore is not ready yet */
		ret = !!score->ifa;
		break;
	case IPV6_SADDR_RULE_LOCAL:
		/* Rule 1: Prefer same address */
		ret = ipv6_addr_equal(&score->ifa->addr, dst->addr);
		break;
	case IPV6_SADDR_RULE_SCOPE:

Annotation

Implementation Notes