Path: blob/main/sys/netpfil/ipfw/nat64/nat64_translate.h
39507 views
/*-1* SPDX-License-Identifier: BSD-2-Clause2*3* Copyright (c) 2015-2019 Yandex LLC4* Copyright (c) 2015-2019 Andrey V. Elsukov <[email protected]>5*6* Redistribution and use in source and binary forms, with or without7* modification, are permitted provided that the following conditions8* are met:9*10* 1. Redistributions of source code must retain the above copyright11* notice, this list of conditions and the following disclaimer.12* 2. Redistributions in binary form must reproduce the above copyright13* notice, this list of conditions and the following disclaimer in the14* documentation and/or other materials provided with the distribution.15*16* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR17* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES18* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.19* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,20* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT21* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,22* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY23* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT24* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF25* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.26*/2728#ifndef _IP_FW_NAT64_TRANSLATE_H_29#define _IP_FW_NAT64_TRANSLATE_H_3031struct nat64_stats {32uint64_t opcnt64; /* 6to4 of packets translated */33uint64_t opcnt46; /* 4to6 of packets translated */34uint64_t ofrags; /* number of fragments generated */35uint64_t ifrags; /* number of fragments received */36uint64_t oerrors; /* number of output errors */37uint64_t noroute4;38uint64_t noroute6;39uint64_t nomatch4; /* No addr/port match */40uint64_t noproto; /* Protocol not supported */41uint64_t nomem; /* mbufs allocation failed */42uint64_t dropped; /* number of packets silently43* dropped due to some errors/44* unsupported/etc.45*/4647uint64_t jrequests; /* jobs requests queued */48uint64_t jcalls; /* jobs handler calls */49uint64_t jhostsreq; /* hosts requests */50uint64_t jportreq; /* PG allocation requests */51uint64_t jhostfails; /* hosts requests failed */52uint64_t jportfails; /* PG allocation failed */53uint64_t jmaxlen;54uint64_t jnomem;55uint64_t jreinjected;5657uint64_t screated;58uint64_t sdeleted;59uint64_t spgcreated;60uint64_t spgdeleted;61};6263#define IPFW_NAT64_VERSION 164#define NAT64STATS (sizeof(struct nat64_stats) / sizeof(uint64_t))65struct nat64_counters {66counter_u64_t cnt[NAT64STATS];67};68#define NAT64STAT_ADD(s, f, v) \69counter_u64_add((s)->cnt[ \70offsetof(struct nat64_stats, f) / sizeof(uint64_t)], (v))71#define NAT64STAT_INC(s, f) NAT64STAT_ADD(s, f, 1)72#define NAT64STAT_FETCH(s, f) \73counter_u64_fetch((s)->cnt[ \74offsetof(struct nat64_stats, f) / sizeof(uint64_t)])7576#define L3HDR(_ip, _t) ((_t)((uint32_t *)(_ip) + (_ip)->ip_hl))77#define TCP(p) ((struct tcphdr *)(p))78#define UDP(p) ((struct udphdr *)(p))79#define ICMP(p) ((struct icmphdr *)(p))80#define ICMP6(p) ((struct icmp6_hdr *)(p))8182#define NAT64SKIP 083#define NAT64RETURN 184#define NAT64MFREE -18586/*87* According to RFC6877:88* PLAT is provider-side translator (XLAT) that translates N:1 global89* IPv6 addresses to global IPv4 addresses, and vice versa.90*91* CLAT is customer-side translator (XLAT) that algorithmically92* translates 1:1 private IPv4 addresses to global IPv6 addresses,93* and vice versa.94*/95struct nat64_config {96struct in6_addr clat_prefix;97struct in6_addr plat_prefix;98uint32_t flags;99#define NAT64_WKPFX 0x00010000 /* prefix is well-known */100#define NAT64_CLATPFX 0x00020000 /* dst prefix is configured */101#define NAT64_PLATPFX 0x00040000 /* src prefix is configured */102uint8_t clat_plen;103uint8_t plat_plen;104105struct nat64_counters stats;106};107108static inline int109nat64_check_ip6(struct in6_addr *addr)110{111112/* XXX: We should really check /8 */113if (addr->s6_addr16[0] == 0 || /* 0000::/8 Reserved by IETF */114IN6_IS_ADDR_MULTICAST(addr) || IN6_IS_ADDR_LINKLOCAL(addr))115return (1);116return (0);117}118119static inline int120nat64_check_ip4(in_addr_t ia)121{122123/* These checks are ordered from most likely to least */124if (IN_MULTICAST(ntohl(ia)) || IN_LOOPBACK(ntohl(ia)) ||125IN_LINKLOCAL(ntohl(ia)) || IN_EXPERIMENTAL(ntohl(ia)))126return (1);127return (0);128}129130/* Well-known prefix 64:ff9b::/96 */131#define IPV6_ADDR_INT32_WKPFX htonl(0x64ff9b)132#define IN6_IS_ADDR_WKPFX(a) \133((a)->s6_addr32[0] == IPV6_ADDR_INT32_WKPFX && \134(a)->s6_addr32[1] == 0 && (a)->s6_addr32[2] == 0)135136int nat64_check_private_ip4(const struct nat64_config *cfg, in_addr_t ia);137int nat64_check_prefixlen(int length);138int nat64_check_prefix6(const struct in6_addr *prefix, int length);139int nat64_getlasthdr(struct mbuf *m, int *offset);140int nat64_do_handle_ip4(struct mbuf *m, struct in6_addr *saddr,141struct in6_addr *daddr, uint16_t lport, struct nat64_config *cfg,142void *logdata);143int nat64_do_handle_ip6(struct mbuf *m, uint32_t aaddr, uint16_t aport,144struct nat64_config *cfg, void *logdata);145int nat64_handle_icmp6(struct mbuf *m, int hlen, uint32_t aaddr,146uint16_t aport, struct nat64_config *cfg, void *logdata);147void nat64_embed_ip4(struct in6_addr *ip6, int plen, in_addr_t ia);148in_addr_t nat64_extract_ip4(const struct in6_addr *ip6, int plen);149150void nat64_set_output_method(int);151int nat64_get_output_method(void);152153#endif154155156