#ifndef _NETIPSEC_IPSEC_H_
#define _NETIPSEC_IPSEC_H_
#include <net/pfkeyv2.h>
#include <netipsec/keydb.h>
#ifdef _KERNEL
#include <sys/_lock.h>
#include <sys/_mutex.h>
#include <sys/_rwlock.h>
#include <sys/sysctl.h>
#include <netinet/in_kdtrace.h>
#define IPSEC_ASSERT(_c,_m) KASSERT(_c, _m)
struct secpolicyindex {
union sockaddr_union src;
union sockaddr_union dst;
uint8_t ul_proto;
uint8_t dir;
uint8_t prefs;
uint8_t prefd;
};
struct ipsecrequest {
struct secasindex saidx;
u_int level;
};
struct ipsec_accel_adddel_sp_tq {
struct vnet *adddel_vnet;
struct task adddel_task;
int adddel_scheduled;
};
struct secpolicy {
TAILQ_ENTRY(secpolicy) chain;
LIST_ENTRY(secpolicy) idhash;
LIST_ENTRY(secpolicy) drainq;
struct secpolicyindex spidx;
#define IPSEC_MAXREQ 4
struct ipsecrequest *req[IPSEC_MAXREQ];
u_int tcount;
volatile u_int refcnt;
u_int policy;
u_int state;
#define IPSEC_SPSTATE_DEAD 0
#define IPSEC_SPSTATE_LARVAL 1
#define IPSEC_SPSTATE_ALIVE 2
#define IPSEC_SPSTATE_PCB 3
#define IPSEC_SPSTATE_IFNET 4
uint32_t priority;
uint32_t id;
time_t created;
time_t lastused;
long lifetime;
long validtime;
CK_LIST_HEAD(, ifp_handle_sp) accel_ifps;
struct ipsec_accel_adddel_sp_tq accel_add_tq;
struct ipsec_accel_adddel_sp_tq accel_del_tq;
struct inpcb *ipsec_accel_add_sp_inp;
const char *accel_ifname;
};
struct inpcbpolicy {
struct secpolicy *sp_in;
struct secpolicy *sp_out;
uint32_t genid;
uint16_t flags;
#define INP_INBOUND_POLICY 0x0001
#define INP_OUTBOUND_POLICY 0x0002
uint16_t hdrsz;
};
struct secspacq {
LIST_ENTRY(secspacq) chain;
struct secpolicyindex spidx;
time_t created;
int count;
};
#endif
#define IPSEC_ADDRSTRLEN (INET6_ADDRSTRLEN + 11)
#define IPSEC_PORT_ANY 0
#define IPSEC_ULPROTO_ANY 255
#define IPSEC_PROTO_ANY 255
#define IPSEC_MODE_ANY 0
#define IPSEC_MODE_TRANSPORT 1
#define IPSEC_MODE_TUNNEL 2
#define IPSEC_MODE_TCPMD5 3
#define IPSEC_DIR_ANY 0
#define IPSEC_DIR_INBOUND 1
#define IPSEC_DIR_OUTBOUND 2
#define IPSEC_DIR_MAX 3
#define IPSEC_DIR_INVALID 4
#define IPSEC_POLICY_DISCARD 0
#define IPSEC_POLICY_NONE 1
#define IPSEC_POLICY_IPSEC 2
#define IPSEC_POLICY_ENTRUST 3
#define IPSEC_POLICY_BYPASS 4
#define IPSEC_POLICYSCOPE_ANY 0x00
#define IPSEC_POLICYSCOPE_GLOBAL 0x01
#define IPSEC_POLICYSCOPE_IFNET 0x02
#define IPSEC_POLICYSCOPE_PCB 0x04
#define IPSEC_LEVEL_DEFAULT 0
#define IPSEC_LEVEL_USE 1
#define IPSEC_LEVEL_REQUIRE 2
#define IPSEC_LEVEL_UNIQUE 3
#define IPSEC_MANUAL_REQID_MAX 0x3fff
#define IPSEC_REPLAYWSIZE 32
struct ipsecstat {
uint64_t ips_in_polvio;
uint64_t ips_in_nomem;
uint64_t ips_in_inval;
uint64_t ips_out_polvio;
uint64_t ips_out_nosa;
uint64_t ips_out_nomem;
uint64_t ips_out_noroute;
uint64_t ips_out_inval;
uint64_t ips_out_bundlesa;
uint64_t ips_spdcache_hits;
uint64_t ips_spdcache_misses;
uint64_t ips_clcopied;
uint64_t ips_mbinserted;
uint64_t ips_input_front;
uint64_t ips_input_middle;
uint64_t ips_input_end;
};
#define IPSECCTL_STATS 1
#define IPSECCTL_DEF_POLICY 2
#define IPSECCTL_DEF_ESP_TRANSLEV 3
#define IPSECCTL_DEF_ESP_NETLEV 4
#define IPSECCTL_DEF_AH_TRANSLEV 5
#define IPSECCTL_DEF_AH_NETLEV 6
#if 0
#define IPSECCTL_INBOUND_CALL_IKE 7
#endif
#define IPSECCTL_AH_CLEARTOS 8
#define IPSECCTL_AH_OFFSETMASK 9
#define IPSECCTL_DFBIT 10
#define IPSECCTL_ECN 11
#define IPSECCTL_DEBUG 12
#define IPSECCTL_ESP_RANDPAD 13
#define IPSECCTL_MIN_PMTU 14
#define IPSECCTL_RANDOM_ID 15
#ifdef _KERNEL
#include <sys/counter.h>
struct ipsec_ctx_data;
#define IPSEC_INIT_CTX(_ctx, _mp, _inp, _sav, _af, _enc) do { \
(_ctx)->mp = (_mp); \
(_ctx)->inp = (_inp); \
(_ctx)->sav = (_sav); \
(_ctx)->af = (_af); \
(_ctx)->enc = (_enc); \
} while(0)
int ipsec_run_hhooks(struct ipsec_ctx_data *ctx, int direction);
VNET_DECLARE(int, ipsec_debug);
#define V_ipsec_debug VNET(ipsec_debug)
#ifdef REGRESSION
VNET_DECLARE(int, ipsec_replay);
VNET_DECLARE(int, ipsec_integrity);
#define V_ipsec_replay VNET(ipsec_replay)
#define V_ipsec_integrity VNET(ipsec_integrity)
#endif
VNET_PCPUSTAT_DECLARE(struct ipsecstat, ipsec4stat);
VNET_DECLARE(int, ip4_esp_trans_deflev);
VNET_DECLARE(int, ip4_esp_net_deflev);
VNET_DECLARE(int, ip4_ah_trans_deflev);
VNET_DECLARE(int, ip4_ah_net_deflev);
VNET_DECLARE(int, ip4_ipsec_dfbit);
VNET_DECLARE(int, ip4_ipsec_min_pmtu);
VNET_DECLARE(int, ip4_ipsec_ecn);
VNET_DECLARE(int, ip4_ipsec_random_id);
VNET_DECLARE(int, crypto_support);
VNET_DECLARE(int, async_crypto);
VNET_DECLARE(int, natt_cksum_policy);
#define IPSECSTAT_INC(name) \
do { \
MIB_SDT_PROBE1(ipsec, count, name, 1); \
VNET_PCPUSTAT_ADD(struct ipsecstat, ipsec4stat, name, 1); \
} while (0)
#define V_ip4_esp_trans_deflev VNET(ip4_esp_trans_deflev)
#define V_ip4_esp_net_deflev VNET(ip4_esp_net_deflev)
#define V_ip4_ah_trans_deflev VNET(ip4_ah_trans_deflev)
#define V_ip4_ah_net_deflev VNET(ip4_ah_net_deflev)
#define V_ip4_ipsec_dfbit VNET(ip4_ipsec_dfbit)
#define V_ip4_ipsec_min_pmtu VNET(ip4_ipsec_min_pmtu)
#define V_ip4_ipsec_ecn VNET(ip4_ipsec_ecn)
#define V_ip4_ipsec_random_id VNET(ip4_ipsec_random_id)
#define V_crypto_support VNET(crypto_support)
#define V_async_crypto VNET(async_crypto)
#define V_natt_cksum_policy VNET(natt_cksum_policy)
#define ipseclog(x) do { if (V_ipsec_debug) log x; } while (0)
#ifdef IPSEC_DEBUG
#define IPSEC_DEBUG_DECLARE(x) x
#define DPRINTF(x) do { if (V_ipsec_debug) printf x; } while (0)
#else
#define IPSEC_DEBUG_DECLARE(x)
#define DPRINTF(x)
#endif
struct inpcb;
struct ip;
struct m_tag;
struct secasvar;
struct sockopt;
struct tcphdr;
union sockaddr_union;
int ipsec_if_input(struct mbuf *, struct secasvar *, uint32_t);
struct ipsecrequest *ipsec_newisr(void);
void ipsec_delisr(struct ipsecrequest *);
struct secpolicy *ipsec4_checkpolicy(const struct mbuf *, struct inpcb *,
struct ip *, int *, int);
u_int ipsec_get_reqlevel(struct secpolicy *, u_int);
void udp_ipsec_adjust_cksum(struct mbuf *, struct secasvar *, int, int);
int udp_ipsec_output(struct mbuf *, struct secasvar *);
int ipsec_chkreplay(uint32_t, uint32_t *, struct secasvar *);
int ipsec_updatereplay(uint32_t, struct secasvar *);
int ipsec_updateid(struct secasvar *, crypto_session_t *, crypto_session_t *);
int ipsec_initialized(void);
size_t ipsec_hdrsiz_internal(struct secpolicy *);
void ipsec_setspidx_inpcb(struct inpcb *, struct secpolicyindex *, u_int);
void ipsec4_setsockaddrs(const struct mbuf *, const struct ip *,
union sockaddr_union *, union sockaddr_union *);
int ipsec4_common_input_cb(struct mbuf *, struct secasvar *, int, int);
int ipsec4_check_pmtu(struct ifnet *, struct mbuf *, struct ip *ip1,
struct secpolicy *, int);
int ipsec4_process_packet(struct ifnet *, struct mbuf *, struct ip *ip1,
struct secpolicy *, struct inpcb *, u_long);
int ipsec_process_done(struct mbuf *, struct secpolicy *, struct secasvar *,
u_int);
void m_checkalignment(const char* where, struct mbuf *m0,
int off, int len);
struct mbuf *m_makespace(struct mbuf *m0, int skip, int hlen, int *off);
caddr_t m_pad(struct mbuf *m, int n);
int m_striphdr(struct mbuf *m, int skip, int hlen);
SYSCTL_DECL(_net_inet_ipsec);
SYSCTL_DECL(_net_inet6_ipsec6);
#endif
#ifndef _KERNEL
caddr_t ipsec_set_policy(const char *, int);
int ipsec_get_policylen(c_caddr_t);
char *ipsec_dump_policy(c_caddr_t, const char *);
const char *ipsec_strerror(void);
#endif
#endif