linux/include/net/inet_ecn.h

/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _INET_ECN_H_
#define _INET_ECN_H_

#include <linux/ip.h>
#include <linux/skbuff.h>
#include <linux/if_vlan.h>

#include <net/inet_sock.h>
#include <net/dsfield.h>
#include <net/checksum.h>

enum {};

extern int sysctl_tunnel_ecn_log;

static inline int INET_ECN_is_ce(__u8 dsfield)
{}

static inline int INET_ECN_is_not_ect(__u8 dsfield)
{}

static inline int INET_ECN_is_capable(__u8 dsfield)
{}

/*
 * RFC 3168 9.1.1
 *  The full-functionality option for ECN encapsulation is to copy the
 *  ECN codepoint of the inside header to the outside header on
 *  encapsulation if the inside header is not-ECT or ECT, and to set the
 *  ECN codepoint of the outside header to ECT(0) if the ECN codepoint of
 *  the inside header is CE.
 */
static inline __u8 INET_ECN_encapsulate(__u8 outer, __u8 inner)
{}

static inline void INET_ECN_xmit(struct sock *sk)
{}

static inline void INET_ECN_dontxmit(struct sock *sk)
{}

#define IP6_ECN_flow_init(label)

#define IP6_ECN_flow_xmit(sk, label)

static inline int IP_ECN_set_ce(struct iphdr *iph)
{}

static inline int IP_ECN_set_ect1(struct iphdr *iph)
{}

static inline void IP_ECN_clear(struct iphdr *iph)
{}

static inline void ipv4_copy_dscp(unsigned int dscp, struct iphdr *inner)
{}

struct ipv6hdr;

/* Note:
 * IP_ECN_set_ce() has to tweak IPV4 checksum when setting CE,
 * meaning both changes have no effect on skb->csum if/when CHECKSUM_COMPLETE
 * In IPv6 case, no checksum compensates the change in IPv6 header,
 * so we have to update skb->csum.
 */
static inline int IP6_ECN_set_ce(struct sk_buff *skb, struct ipv6hdr *iph)
{}

static inline int IP6_ECN_set_ect1(struct sk_buff *skb, struct ipv6hdr *iph)
{}

static inline void ipv6_copy_dscp(unsigned int dscp, struct ipv6hdr *inner)
{}

static inline int INET_ECN_set_ce(struct sk_buff *skb)
{}

static inline int skb_get_dsfield(struct sk_buff *skb)
{}

static inline int INET_ECN_set_ect1(struct sk_buff *skb)
{}

/*
 * RFC 6040 4.2
 *  To decapsulate the inner header at the tunnel egress, a compliant
 *  tunnel egress MUST set the outgoing ECN field to the codepoint at the
 *  intersection of the appropriate arriving inner header (row) and outer
 *  header (column) in Figure 4
 *
 *      +---------+------------------------------------------------+
 *      |Arriving |            Arriving Outer Header               |
 *      |   Inner +---------+------------+------------+------------+
 *      |  Header | Not-ECT | ECT(0)     | ECT(1)     |     CE     |
 *      +---------+---------+------------+------------+------------+
 *      | Not-ECT | Not-ECT |Not-ECT(!!!)|Not-ECT(!!!)| <drop>(!!!)|
 *      |  ECT(0) |  ECT(0) | ECT(0)     | ECT(1)     |     CE     |
 *      |  ECT(1) |  ECT(1) | ECT(1) (!) | ECT(1)     |     CE     |
 *      |    CE   |      CE |     CE     |     CE(!!!)|     CE     |
 *      +---------+---------+------------+------------+------------+
 *
 *             Figure 4: New IP in IP Decapsulation Behaviour
 *
 *  returns 0 on success
 *          1 if something is broken and should be logged (!!! above)
 *          2 if packet should be dropped
 */
static inline int __INET_ECN_decapsulate(__u8 outer, __u8 inner, bool *set_ce)
{}

static inline int INET_ECN_decapsulate(struct sk_buff *skb,
				       __u8 outer, __u8 inner)
{}

static inline int IP_ECN_decapsulate(const struct iphdr *oiph,
				     struct sk_buff *skb)
{}

static inline int IP6_ECN_decapsulate(const struct ipv6hdr *oipv6h,
				      struct sk_buff *skb)
{}
#endif