net/ipv4/xfrm4_policy.c

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

File Facts

System
Linux kernel
Corpus path
net/ipv4/xfrm4_policy.c
Extension
.c
Size
5794 bytes
Lines
246
Domain
Networking Core
Bucket
Sockets, Protocols, Packet Path, And Network Policy
Inferred role
Networking Core: implementation source
Status
source 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

// SPDX-License-Identifier: GPL-2.0
/*
 * xfrm4_policy.c
 *
 * Changes:
 *	Kazunori MIYAZAWA @USAGI
 * 	YOSHIFUJI Hideaki @USAGI
 *		Split up af-specific portion
 *
 */

#include <linux/err.h>
#include <linux/kernel.h>
#include <linux/inetdevice.h>
#include <net/dst.h>
#include <net/xfrm.h>
#include <net/flow.h>
#include <net/ip.h>
#include <net/l3mdev.h>

static struct dst_entry *__xfrm4_dst_lookup(struct flowi4 *fl4,
					    const struct xfrm_dst_lookup_params *params)
{
	struct rtable *rt;

	memset(fl4, 0, sizeof(*fl4));
	fl4->daddr = params->daddr->a4;
	fl4->flowi4_dscp = params->dscp;
	fl4->flowi4_l3mdev = l3mdev_master_ifindex_by_index(params->net,
							    params->oif);
	fl4->flowi4_mark = params->mark;
	if (params->saddr)
		fl4->saddr = params->saddr->a4;
	fl4->flowi4_proto = params->ipproto;
	fl4->uli = params->uli;

	rt = __ip_route_output_key(params->net, fl4);
	if (!IS_ERR(rt))
		return &rt->dst;

	return ERR_CAST(rt);
}

static struct dst_entry *xfrm4_dst_lookup(const struct xfrm_dst_lookup_params *params)
{
	struct flowi4 fl4;

	return __xfrm4_dst_lookup(&fl4, params);
}

static int xfrm4_get_saddr(xfrm_address_t *saddr,
			   const struct xfrm_dst_lookup_params *params)
{
	struct dst_entry *dst;
	struct flowi4 fl4;

	dst = __xfrm4_dst_lookup(&fl4, params);
	if (IS_ERR(dst))
		return -EHOSTUNREACH;

	saddr->a4 = fl4.saddr;
	dst_release(dst);
	return 0;
}

static int xfrm4_fill_dst(struct xfrm_dst *xdst, struct net_device *dev,
			  const struct flowi *fl)
{
	struct rtable *rt = dst_rtable(xdst->route);
	const struct flowi4 *fl4 = &fl->u.ip4;

	xdst->u.rt.rt_iif = fl4->flowi4_iif;

	xdst->u.dst.dev = dev;
	netdev_hold(dev, &xdst->u.dst.dev_tracker, GFP_ATOMIC);

	/* Sheit... I remember I did this right. Apparently,
	 * it was magically lost, so this code needs audit */
	xdst->u.rt.rt_is_input = rt->rt_is_input;
	xdst->u.rt.rt_flags = rt->rt_flags & (RTCF_BROADCAST | RTCF_MULTICAST |
					      RTCF_LOCAL);
	xdst->u.rt.rt_type = rt->rt_type;
	xdst->u.rt.rt_uses_gateway = rt->rt_uses_gateway;
	xdst->u.rt.rt_gw_family = rt->rt_gw_family;
	if (rt->rt_gw_family == AF_INET)
		xdst->u.rt.rt_gw4 = rt->rt_gw4;
	else if (rt->rt_gw_family == AF_INET6)
		xdst->u.rt.rt_gw6 = rt->rt_gw6;
	xdst->u.rt.rt_pmtu = rt->rt_pmtu;
	xdst->u.rt.rt_mtu_locked = rt->rt_mtu_locked;

Annotation

Implementation Notes