linux/net/ipv6/ip6_output.c

// SPDX-License-Identifier: GPL-2.0-or-later
/*
 *	IPv6 output functions
 *	Linux INET6 implementation
 *
 *	Authors:
 *	Pedro Roque		<[email protected]>
 *
 *	Based on linux/net/ipv4/ip_output.c
 *
 *	Changes:
 *	A.N.Kuznetsov	:	airthmetics in fragmentation.
 *				extension headers are implemented.
 *				route changes now work.
 *				ip6_forward does not confuse sniffers.
 *				etc.
 *
 *      H. von Brand    :       Added missing #include <linux/string.h>
 *	Imran Patel	:	frag id should be in NBO
 *      Kazunori MIYAZAWA @USAGI
 *			:       add ip6_append_data and related functions
 *				for datagram xmit
 */

#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/socket.h>
#include <linux/net.h>
#include <linux/netdevice.h>
#include <linux/if_arp.h>
#include <linux/in6.h>
#include <linux/tcp.h>
#include <linux/route.h>
#include <linux/module.h>
#include <linux/slab.h>

#include <linux/bpf-cgroup.h>
#include <linux/netfilter.h>
#include <linux/netfilter_ipv6.h>

#include <net/sock.h>
#include <net/snmp.h>

#include <net/gso.h>
#include <net/ipv6.h>
#include <net/ndisc.h>
#include <net/protocol.h>
#include <net/ip6_route.h>
#include <net/addrconf.h>
#include <net/rawv6.h>
#include <net/icmp.h>
#include <net/xfrm.h>
#include <net/checksum.h>
#include <linux/mroute6.h>
#include <net/l3mdev.h>
#include <net/lwtunnel.h>
#include <net/ip_tunnels.h>

static int ip6_finish_output2(struct net *net, struct sock *sk, struct sk_buff *skb)
{}

static int
ip6_finish_output_gso_slowpath_drop(struct net *net, struct sock *sk,
				    struct sk_buff *skb, unsigned int mtu)
{}

static int ip6_finish_output_gso(struct net *net, struct sock *sk,
				 struct sk_buff *skb, unsigned int mtu)
{}

static int __ip6_finish_output(struct net *net, struct sock *sk, struct sk_buff *skb)
{}

static int ip6_finish_output(struct net *net, struct sock *sk, struct sk_buff *skb)
{}

int ip6_output(struct net *net, struct sock *sk, struct sk_buff *skb)
{}
EXPORT_SYMBOL();

bool ip6_autoflowlabel(struct net *net, const struct sock *sk)
{}

/*
 * xmit an sk_buff (used by TCP, SCTP and DCCP)
 * Note : socket lock is not held for SYNACK packets, but might be modified
 * by calls to skb_set_owner_w() and ipv6_local_error(),
 * which are using proper atomic operations or spinlocks.
 */
int ip6_xmit(const struct sock *sk, struct sk_buff *skb, struct flowi6 *fl6,
	     __u32 mark, struct ipv6_txoptions *opt, int tclass, u32 priority)
{}
EXPORT_SYMBOL();

static int ip6_call_ra_chain(struct sk_buff *skb, int sel)
{}

static int ip6_forward_proxy_check(struct sk_buff *skb)
{}

static inline int ip6_forward_finish(struct net *net, struct sock *sk,
				     struct sk_buff *skb)
{}

static bool ip6_pkt_too_big(const struct sk_buff *skb, unsigned int mtu)
{}

int ip6_forward(struct sk_buff *skb)
{}

static void ip6_copy_metadata(struct sk_buff *to, struct sk_buff *from)
{}

int ip6_fraglist_init(struct sk_buff *skb, unsigned int hlen, u8 *prevhdr,
		      u8 nexthdr, __be32 frag_id,
		      struct ip6_fraglist_iter *iter)
{}
EXPORT_SYMBOL();

void ip6_fraglist_prepare(struct sk_buff *skb,
			  struct ip6_fraglist_iter *iter)
{}
EXPORT_SYMBOL();

void ip6_frag_init(struct sk_buff *skb, unsigned int hlen, unsigned int mtu,
		   unsigned short needed_tailroom, int hdr_room, u8 *prevhdr,
		   u8 nexthdr, __be32 frag_id, struct ip6_frag_state *state)
{}
EXPORT_SYMBOL();

struct sk_buff *ip6_frag_next(struct sk_buff *skb, struct ip6_frag_state *state)
{}
EXPORT_SYMBOL();

int ip6_fragment(struct net *net, struct sock *sk, struct sk_buff *skb,
		 int (*output)(struct net *, struct sock *, struct sk_buff *))
{}

static inline int ip6_rt_check(const struct rt6key *rt_key,
			       const struct in6_addr *fl_addr,
			       const struct in6_addr *addr_cache)
{}

static struct dst_entry *ip6_sk_dst_check(struct sock *sk,
					  struct dst_entry *dst,
					  const struct flowi6 *fl6)
{}

static int ip6_dst_lookup_tail(struct net *net, const struct sock *sk,
			       struct dst_entry **dst, struct flowi6 *fl6)
{}

/**
 *	ip6_dst_lookup - perform route lookup on flow
 *	@net: Network namespace to perform lookup in
 *	@sk: socket which provides route info
 *	@dst: pointer to dst_entry * for result
 *	@fl6: flow to lookup
 *
 *	This function performs a route lookup on the given flow.
 *
 *	It returns zero on success, or a standard errno code on error.
 */
int ip6_dst_lookup(struct net *net, struct sock *sk, struct dst_entry **dst,
		   struct flowi6 *fl6)
{}
EXPORT_SYMBOL_GPL();

/**
 *	ip6_dst_lookup_flow - perform route lookup on flow with ipsec
 *	@net: Network namespace to perform lookup in
 *	@sk: socket which provides route info
 *	@fl6: flow to lookup
 *	@final_dst: final destination address for ipsec lookup
 *
 *	This function performs a route lookup on the given flow.
 *
 *	It returns a valid dst pointer on success, or a pointer encoded
 *	error code.
 */
struct dst_entry *ip6_dst_lookup_flow(struct net *net, const struct sock *sk, struct flowi6 *fl6,
				      const struct in6_addr *final_dst)
{}
EXPORT_SYMBOL_GPL();

/**
 *	ip6_sk_dst_lookup_flow - perform socket cached route lookup on flow
 *	@sk: socket which provides the dst cache and route info
 *	@fl6: flow to lookup
 *	@final_dst: final destination address for ipsec lookup
 *	@connected: whether @sk is connected or not
 *
 *	This function performs a route lookup on the given flow with the
 *	possibility of using the cached route in the socket if it is valid.
 *	It will take the socket dst lock when operating on the dst cache.
 *	As a result, this function can only be used in process context.
 *
 *	In addition, for a connected socket, cache the dst in the socket
 *	if the current cache is not valid.
 *
 *	It returns a valid dst pointer on success, or a pointer encoded
 *	error code.
 */
struct dst_entry *ip6_sk_dst_lookup_flow(struct sock *sk, struct flowi6 *fl6,
					 const struct in6_addr *final_dst,
					 bool connected)
{}
EXPORT_SYMBOL_GPL();

static inline struct ipv6_opt_hdr *ip6_opt_dup(struct ipv6_opt_hdr *src,
					       gfp_t gfp)
{}

static inline struct ipv6_rt_hdr *ip6_rthdr_dup(struct ipv6_rt_hdr *src,
						gfp_t gfp)
{}

static void ip6_append_data_mtu(unsigned int *mtu,
				int *maxfraglen,
				unsigned int fragheaderlen,
				struct sk_buff *skb,
				struct rt6_info *rt,
				unsigned int orig_mtu)
{}

static int ip6_setup_cork(struct sock *sk, struct inet_cork_full *cork,
			  struct inet6_cork *v6_cork, struct ipcm6_cookie *ipc6,
			  struct rt6_info *rt)
{}

static int __ip6_append_data(struct sock *sk,
			     struct sk_buff_head *queue,
			     struct inet_cork_full *cork_full,
			     struct inet6_cork *v6_cork,
			     struct page_frag *pfrag,
			     int getfrag(void *from, char *to, int offset,
					 int len, int odd, struct sk_buff *skb),
			     void *from, size_t length, int transhdrlen,
			     unsigned int flags, struct ipcm6_cookie *ipc6)
{}

int ip6_append_data(struct sock *sk,
		    int getfrag(void *from, char *to, int offset, int len,
				int odd, struct sk_buff *skb),
		    void *from, size_t length, int transhdrlen,
		    struct ipcm6_cookie *ipc6, struct flowi6 *fl6,
		    struct rt6_info *rt, unsigned int flags)
{}
EXPORT_SYMBOL_GPL();

static void ip6_cork_steal_dst(struct sk_buff *skb, struct inet_cork_full *cork)
{}

static void ip6_cork_release(struct inet_cork_full *cork,
			     struct inet6_cork *v6_cork)
{}

struct sk_buff *__ip6_make_skb(struct sock *sk,
			       struct sk_buff_head *queue,
			       struct inet_cork_full *cork,
			       struct inet6_cork *v6_cork)
{}

int ip6_send_skb(struct sk_buff *skb)
{}

int ip6_push_pending_frames(struct sock *sk)
{}
EXPORT_SYMBOL_GPL();

static void __ip6_flush_pending_frames(struct sock *sk,
				       struct sk_buff_head *queue,
				       struct inet_cork_full *cork,
				       struct inet6_cork *v6_cork)
{}

void ip6_flush_pending_frames(struct sock *sk)
{}
EXPORT_SYMBOL_GPL();

struct sk_buff *ip6_make_skb(struct sock *sk,
			     int getfrag(void *from, char *to, int offset,
					 int len, int odd, struct sk_buff *skb),
			     void *from, size_t length, int transhdrlen,
			     struct ipcm6_cookie *ipc6, struct rt6_info *rt,
			     unsigned int flags, struct inet_cork_full *cork)
{}