net/ipv6/sit.c

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

File Facts

System
Linux kernel
Corpus path
net/ipv6/sit.c
Extension
.c
Size
46771 bytes
Lines
1951
Domain
Networking Core
Bucket
Sockets, Protocols, Packet Path, And Network Policy
Inferred role
Networking Core: operation-table or driver-model contract
Status
pattern 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

static const struct net_device_ops ipip6_netdev_ops = {
	.ndo_init	= ipip6_tunnel_init,
	.ndo_uninit	= ipip6_tunnel_uninit,
	.ndo_start_xmit	= sit_tunnel_xmit,
	.ndo_siocdevprivate = ipip6_tunnel_siocdevprivate,
	.ndo_get_iflink = ip_tunnel_get_iflink,
	.ndo_tunnel_ctl = ipip6_tunnel_ctl,
};

static void ipip6_dev_free(struct net_device *dev)
{
	struct ip_tunnel *tunnel = netdev_priv(dev);

	dst_cache_destroy(&tunnel->dst_cache);
}

#define SIT_FEATURES (NETIF_F_SG	   | \
		      NETIF_F_FRAGLIST	   | \
		      NETIF_F_HIGHDMA	   | \
		      NETIF_F_GSO_SOFTWARE | \
		      NETIF_F_HW_CSUM)

static void ipip6_tunnel_setup(struct net_device *dev)
{
	struct ip_tunnel *tunnel = netdev_priv(dev);
	int t_hlen = tunnel->hlen + sizeof(struct iphdr);

	dev->netdev_ops		= &ipip6_netdev_ops;
	dev->header_ops		= &ip_tunnel_header_ops;
	dev->needs_free_netdev	= true;
	dev->priv_destructor	= ipip6_dev_free;

	dev->type		= ARPHRD_SIT;
	dev->mtu		= ETH_DATA_LEN - t_hlen;
	dev->min_mtu		= IPV6_MIN_MTU;
	dev->max_mtu		= IP6_MAX_MTU - t_hlen;
	dev->flags		= IFF_NOARP;
	netif_keep_dst(dev);
	dev->addr_len		= 4;
	dev->lltx		= true;
	dev->features		|= SIT_FEATURES;
	dev->hw_features	|= SIT_FEATURES;
	dev->pcpu_stat_type	= NETDEV_PCPU_STAT_TSTATS;

}

static int ipip6_tunnel_init(struct net_device *dev)
{
	struct ip_tunnel *tunnel = netdev_priv(dev);
	int err;

	tunnel->dev = dev;
	strscpy(tunnel->parms.name, dev->name);

	ipip6_tunnel_bind_dev(dev);

	err = dst_cache_init(&tunnel->dst_cache, GFP_KERNEL);
	if (err)
		return err;

	netdev_hold(dev, &tunnel->dev_tracker, GFP_KERNEL);
	netdev_lockdep_set_classes(dev);
	return 0;
}

static void __net_init ipip6_fb_tunnel_init(struct net_device *dev)
{
	struct ip_tunnel *tunnel = netdev_priv(dev);
	struct iphdr *iph = &tunnel->parms.iph;
	struct net *net = dev_net(dev);
	struct sit_net *sitn = net_generic(net, sit_net_id);

	iph->version		= 4;
	iph->protocol		= IPPROTO_IPV6;
	iph->ihl		= 5;
	iph->ttl		= 64;

	rcu_assign_pointer(sitn->tunnels_wc[0], tunnel);
}

static int ipip6_validate(struct nlattr *tb[], struct nlattr *data[],
			  struct netlink_ext_ack *extack)
{
	u8 proto;

	if (!data || !data[IFLA_IPTUN_PROTO])
		return 0;

	proto = nla_get_u8(data[IFLA_IPTUN_PROTO]);
	if (!ipip6_valid_ip_proto(proto))

Annotation

Implementation Notes