net/ipv4/devinet.c

Source file repositories/reference/linux-study-clean/net/ipv4/devinet.c

File Facts

System
Linux kernel
Corpus path
net/ipv4/devinet.c
Extension
.c
Size
77039 bytes
Lines
2977
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

if (err) {
			in_dev->dead = 1;
			neigh_parms_release(&arp_tbl, in_dev->arp_parms);
			in_dev_put(in_dev);
			in_dev = NULL;
			goto out;
		}
		ip_mc_init_dev(in_dev);
		if (dev->flags & IFF_UP)
			ip_mc_up(in_dev);
	}

	/* we can receive as soon as ip_ptr is set -- do this last */
	rcu_assign_pointer(dev->ip_ptr, in_dev);
out:
	return in_dev ?: ERR_PTR(err);
out_kfree:
	kfree(in_dev);
	in_dev = NULL;
	goto out;
}

static void inetdev_destroy(struct in_device *in_dev)
{
	struct net_device *dev;
	struct in_ifaddr *ifa;

	ASSERT_RTNL();

	dev = in_dev->dev;

	in_dev->dead = 1;

	ip_mc_destroy_dev(in_dev);

	while ((ifa = rtnl_dereference(in_dev->ifa_list)) != NULL) {
		inet_del_ifa(in_dev, &in_dev->ifa_list, 0);
		inet_free_ifa(ifa);
	}

	RCU_INIT_POINTER(dev->ip_ptr, NULL);

	devinet_sysctl_unregister(in_dev);
	neigh_parms_release(&arp_tbl, in_dev->arp_parms);
	arp_ifdown(dev);

	in_dev_put(in_dev);
}

static int __init inet_blackhole_dev_init(void)
{
	struct in_device *in_dev;

	rtnl_lock();
	in_dev = inetdev_init(blackhole_netdev);
	rtnl_unlock();

	return PTR_ERR_OR_ZERO(in_dev);
}
late_initcall(inet_blackhole_dev_init);

int inet_addr_onlink(struct in_device *in_dev, __be32 a, __be32 b)
{
	const struct in_ifaddr *ifa;

	rcu_read_lock();
	in_dev_for_each_ifa_rcu(ifa, in_dev) {
		if (inet_ifa_match(a, ifa)) {
			if (!b || inet_ifa_match(b, ifa)) {
				rcu_read_unlock();
				return 1;
			}
		}
	}
	rcu_read_unlock();
	return 0;
}

static void __inet_del_ifa(struct in_device *in_dev,
			   struct in_ifaddr __rcu **ifap,
			   int destroy, struct nlmsghdr *nlh, u32 portid)
{
	struct in_ifaddr *promote = NULL;
	struct in_ifaddr *ifa, *ifa1;
	struct in_ifaddr __rcu **last_prim;
	struct in_ifaddr *prev_prom = NULL;
	int do_promote = IN_DEV_PROMOTE_SECONDARIES(in_dev);

	ASSERT_RTNL();

Annotation

Implementation Notes