#include <linux/kernel.h>
#include <linux/netdevice.h>
#include <net/addrconf.h>
#include <net/ip6_route.h>
#if IS_ENABLED(CONFIG_IPV6_MIP6)
static struct dst_entry *xfrm6_dst_lookup(struct net *net, int tos, int oif,
const xfrm_address_t *saddr,
const xfrm_address_t *daddr,
memset(&fl6, 0, sizeof(fl6));
fl6.flowi6_oif = l3mdev_master_ifindex_by_index(net, oif);
fl6.flowi6_flags = FLOWI_FLAG_SKIP_NH_OIF;
memcpy(&fl6.daddr, daddr, sizeof(fl6.daddr));
memcpy(&fl6.saddr, saddr, sizeof(fl6.saddr));
dst = ip6_route_output(net, NULL, &fl6);
static int xfrm6_get_saddr(struct net *net, int oif,
xfrm_address_t *saddr, xfrm_address_t *daddr,
dst = xfrm6_dst_lookup(net, 0, oif, NULL, daddr, mark);
dev = ip6_dst_idev(dst)->dev;
ipv6_dev_get_saddr(dev_net(dev), dev, &daddr->in6, 0, &saddr->in6);
static int xfrm6_get_tos(const struct flowi *fl)
static int xfrm6_init_path(struct xfrm_dst *path, struct dst_entry *dst,
if (dst->ops->family == AF_INET6) {
struct rt6_info *rt = (struct rt6_info *)dst;
path->path_cookie = rt6_get_cookie(rt);
path->u.rt6.rt6i_nfheader_len = nfheader_len;
static int xfrm6_fill_dst(struct xfrm_dst *xdst, struct net_device *dev,