From 0eeff2e5f7e44dab02c210b5eccb8d8c1bd99c37 Mon Sep 17 00:00:00 2001 From: "kiselev99@gmail.com" Date: Wed, 17 Jul 2019 21:02:42 +0300 Subject: [PATCH 1/3] add nat events callbacks --- src/kern/npf_conn.c | 29 ++++++++++++++++++++++++++++- src/kern/npf_conn.h | 9 +++++++++ src/kern/npf_connkey.c | 30 ++++++++++++++++++++++++++++++ src/kern/npf_impl.h | 7 ++++++- src/kern/npf_nat.c | 26 ++++++++++++++++++++++++++ src/kern/npfkern.h | 20 ++++++++++++++++++++ 6 files changed, 119 insertions(+), 2 deletions(-) diff --git a/src/kern/npf_conn.c b/src/kern/npf_conn.c index af2cbc34..4eeac6fc 100644 --- a/src/kern/npf_conn.c +++ b/src/kern/npf_conn.c @@ -508,6 +508,18 @@ npf_conn_destroy(npf_t *npf, npf_conn_t *con) if (con->c_nat) { /* Release any NAT structures. */ npf_nat_destroy(con->c_nat); + + /* NAT events: execute destroy ipv4 translation callback */ + if (alen == NPF_IPV4_ALEN && + npf->nat_events_opts.ipv4_destroy_translation != NULL) + npf->nat_events_opts.ipv4_destroy_translation( + npf_conn_key_get_proto(key), + npf_conn_key_ipv4_get_src_addr(key), + npf_conn_key_ipv4_get_src_id(key), + npf_conn_key_ipv4_get_dst_addr(key), + npf_conn_key_ipv4_get_dst_id(key), + npf_nat_gettrans_addr(con->c_nat)->word32[0], + (uint16_t)npf_nat_gettrans_port(con->c_nat)); } if (con->c_rproc) { /* Release the rule procedure. */ @@ -543,6 +555,7 @@ npf_conn_setnat(const npf_cache_t *npc, npf_conn_t *con, npf_conn_t *ret __diagused; npf_addr_t *taddr; in_port_t tport; + unsigned alen; KASSERT(con->c_refcnt > 0); @@ -572,7 +585,8 @@ npf_conn_setnat(const npf_cache_t *npc, npf_conn_t *con, /* Remove the "backwards" key. */ fw = npf_conn_getforwkey(con); - bk = npf_conn_getbackkey(con, NPF_CONNKEY_ALEN(fw)); + alen = NPF_CONNKEY_ALEN(fw); + bk = npf_conn_getbackkey(con, alen); ret = npf_conndb_remove(npf->conn_db, bk); KASSERT(ret == con); @@ -598,6 +612,19 @@ npf_conn_setnat(const npf_cache_t *npc, npf_conn_t *con, /* Associate the NAT entry and release the lock. */ con->c_nat = nt; mutex_exit(&con->c_lock); + + /* NAT events: execute create ipv4 translation callback */ + if (alen == NPF_IPV4_ALEN && + npf->nat_events_opts.ipv4_create_translation != NULL) + npf->nat_events_opts.ipv4_create_translation( + npf_conn_key_get_proto(fw), + npf_conn_key_ipv4_get_src_addr(fw), + npf_conn_key_ipv4_get_src_id(fw), + npf_conn_key_ipv4_get_dst_addr(fw), + npf_conn_key_ipv4_get_dst_id(fw), + npf_nat_gettrans_addr(con->c_nat)->word32[0], + (uint16_t)npf_nat_gettrans_port(con->c_nat)); + return 0; } diff --git a/src/kern/npf_conn.h b/src/kern/npf_conn.h index c2222e84..fd3e2f08 100644 --- a/src/kern/npf_conn.h +++ b/src/kern/npf_conn.h @@ -103,6 +103,9 @@ struct npf_conn { #define NPF_CONNKEY_ALEN(key) ((key)->ck_key[0] & 0xffff) #define NPF_CONNKEY_LEN(key) (8 + (NPF_CONNKEY_ALEN(key) * 2)) +#define NPF_IPV4_ALEN 4 +#define NPF_IPV6_ALEN 16 + struct npf_connkey { /* Warning: ck_key has a variable length -- see above. */ uint32_t ck_key[NPF_CONNKEY_MAXWORDS]; @@ -114,6 +117,12 @@ npf_connkey_t * npf_conn_getbackkey(npf_conn_t *, unsigned); void npf_conn_adjkey(npf_connkey_t *, const npf_addr_t *, const uint16_t, const int); +uint16_t npf_conn_key_get_proto(const npf_connkey_t *); +uint16_t npf_conn_key_ipv4_get_src_id(const npf_connkey_t *); +uint16_t npf_conn_key_ipv4_get_dst_id(const npf_connkey_t *); +uint32_t npf_conn_key_ipv4_get_src_addr(const npf_connkey_t *); +uint32_t npf_conn_key_ipv4_get_dst_addr(const npf_connkey_t *); + unsigned npf_connkey_import(const nvlist_t *, npf_connkey_t *); nvlist_t * npf_connkey_export(const npf_connkey_t *); void npf_connkey_print(const npf_connkey_t *); diff --git a/src/kern/npf_connkey.c b/src/kern/npf_connkey.c index 19a90359..b48c6714 100644 --- a/src/kern/npf_connkey.c +++ b/src/kern/npf_connkey.c @@ -66,6 +66,36 @@ __KERNEL_RCSID(0, "$NetBSD$"); #include "npf_conn.h" #include "npf_impl.h" +uint16_t +npf_conn_key_get_proto(const npf_connkey_t *key) +{ + return (uint16_t) (key->ck_key[0] >> 16); +} + +uint16_t +npf_conn_key_ipv4_get_src_id(const npf_connkey_t *key) +{ + return (uint16_t) (key->ck_key[1] >> 16); +} + +uint16_t +npf_conn_key_ipv4_get_dst_id(const npf_connkey_t *key) +{ + return (uint16_t) (key->ck_key[1] & 0xFFFF); +} + +uint32_t +npf_conn_key_ipv4_get_src_addr(const npf_connkey_t *key) +{ + return key->ck_key[2]; +} + +uint32_t +npf_conn_key_ipv4_get_dst_addr(const npf_connkey_t *key) +{ + return key->ck_key[3]; +} + static inline unsigned connkey_setkey(npf_connkey_t *key, uint16_t proto, const void *ipv, const uint16_t *id, unsigned alen, bool forw) diff --git a/src/kern/npf_impl.h b/src/kern/npf_impl.h index a22abf3e..109829d7 100644 --- a/src/kern/npf_impl.h +++ b/src/kern/npf_impl.h @@ -202,7 +202,7 @@ struct npf { /* BPF byte-code context. */ bpf_ctx_t * bpfctx; const npf_mbufops_t * mbufops; - + /* Parameters. */ npf_paraminfo_t * paraminfo; void * params[NPF_PARAMS_COUNT]; @@ -237,6 +237,9 @@ struct npf { /* Statistics. */ percpu_t * stats_percpu; + + /* NAT events callbacks */ + npf_nat_events_ops_t nat_events_opts; }; /* @@ -481,6 +484,8 @@ int npf_do_nat(npf_cache_t *, npf_conn_t *, const int); void npf_nat_destroy(npf_nat_t *); void npf_nat_getorig(npf_nat_t *, npf_addr_t **, in_port_t *); void npf_nat_gettrans(npf_nat_t *, npf_addr_t **, in_port_t *); +const npf_addr_t * npf_nat_gettrans_addr(const npf_nat_t *); +in_port_t npf_nat_gettrans_port(const npf_nat_t *); void npf_nat_setalg(npf_nat_t *, npf_alg_t *, uintptr_t); void npf_nat_export(nvlist_t *, npf_nat_t *); diff --git a/src/kern/npf_nat.c b/src/kern/npf_nat.c index 1fddfae3..ddec4eba 100644 --- a/src/kern/npf_nat.c +++ b/src/kern/npf_nat.c @@ -709,6 +709,18 @@ npf_nat_gettrans(npf_nat_t *nt, npf_addr_t **addr, in_port_t *port) *port = nt->nt_tport; } +const npf_addr_t * +npf_nat_gettrans_addr(const npf_nat_t *nt) +{ + return &nt->nt_taddr; +} + +in_port_t +npf_nat_gettrans_port(const npf_nat_t *nt) +{ + return nt->nt_tport; +} + /* * npf_nat_getorig: return original IP address and port from translation entry. */ @@ -839,3 +851,17 @@ npf_nat_dump(const npf_nat_t *nt) } #endif + +__dso_public void +npf_nat_events_set_create_ipv4_translation_cb(npf_t *npf, + npf_nat_event_ipv4_create_translation_t cb) +{ + npf->nat_events_opts.ipv4_create_translation = cb; +} + +__dso_public void +npf_nat_events_set_destroy_ipv4_translation_cb(npf_t *npf, + npf_nat_event_ipv4_destroy_translation_t cb) +{ + npf->nat_events_opts.ipv4_destroy_translation = cb; +} \ No newline at end of file diff --git a/src/kern/npfkern.h b/src/kern/npfkern.h index 7d69b589..dabb5221 100644 --- a/src/kern/npfkern.h +++ b/src/kern/npfkern.h @@ -61,6 +61,20 @@ typedef struct { bool (*ensure_writable)(struct mbuf **, size_t); } npf_mbufops_t; +/* NAT event callbacks */ +typedef void (*npf_nat_event_ipv4_create_translation_t) (uint16_t proto, + uint32_t src, uint16_t src_id, uint32_t dst, uint16_t dst_id, + uint32_t tsrc, uint16_t tsrc_id); + +typedef void (*npf_nat_event_ipv4_destroy_translation_t) (uint16_t proto, + uint32_t src, uint16_t src_id, uint32_t dst, uint16_t dst_id, + uint32_t tsrc, uint16_t tsrc_id); + +typedef struct { + npf_nat_event_ipv4_create_translation_t ipv4_create_translation; + npf_nat_event_ipv4_destroy_translation_t ipv4_destroy_translation; +} npf_nat_events_ops_t; + int npf_sysinit(unsigned); void npf_sysfini(void); @@ -86,4 +100,10 @@ void npf_stats_clear(npf_t *); int npf_alg_icmp_init(npf_t *); int npf_alg_icmp_fini(npf_t *); +/* NAT events callbacks */ +void npf_nat_events_set_create_ipv4_translation_cb(npf_t *, + npf_nat_event_ipv4_create_translation_t); +void npf_nat_events_set_destroy_ipv4_translation_cb(npf_t *, + npf_nat_event_ipv4_destroy_translation_t); + #endif From 8050caecc137d091a8bbfda6e50f05020aba2929 Mon Sep 17 00:00:00 2001 From: "kiselev99@gmail.com" Date: Thu, 25 Jul 2019 19:00:13 +0300 Subject: [PATCH 2/3] use npf_connkey_get() instead of new functions --- src/kern/npf_conn.c | 38 ++++++++++++++++++++++---------------- src/kern/npf_conn.h | 10 ---------- src/kern/npf_connkey.c | 30 ------------------------------ src/kern/npfkern.h | 4 ++-- 4 files changed, 24 insertions(+), 58 deletions(-) diff --git a/src/kern/npf_conn.c b/src/kern/npf_conn.c index 4eeac6fc..f387a0c8 100644 --- a/src/kern/npf_conn.c +++ b/src/kern/npf_conn.c @@ -500,7 +500,7 @@ void npf_conn_destroy(npf_t *npf, npf_conn_t *con) { const npf_connkey_t *key = npf_conn_getforwkey(con); - const unsigned alen = NPF_CONNKEY_ALEN(key); + uint16_t alen = NPF_CONNKEY_ALEN(key); const unsigned idx __unused = NPF_CONNCACHE(alen); KASSERT(con->c_refcnt == 0); @@ -510,16 +510,19 @@ npf_conn_destroy(npf_t *npf, npf_conn_t *con) npf_nat_destroy(con->c_nat); /* NAT events: execute destroy ipv4 translation callback */ - if (alen == NPF_IPV4_ALEN && - npf->nat_events_opts.ipv4_destroy_translation != NULL) + if (alen == sizeof(in_addr_t) && + npf->nat_events_opts.ipv4_destroy_translation != NULL) { + uint16_t proto; + uint16_t ids[2]; + npf_addr_t ips[2]; + + npf_connkey_getkey(key, &proto, ips, ids, &alen); npf->nat_events_opts.ipv4_destroy_translation( - npf_conn_key_get_proto(key), - npf_conn_key_ipv4_get_src_addr(key), - npf_conn_key_ipv4_get_src_id(key), - npf_conn_key_ipv4_get_dst_addr(key), - npf_conn_key_ipv4_get_dst_id(key), + proto, ips[NPF_SRC].word32[0], ips[NPF_DST].word32[0], + ids[NPF_SRC], ids[NPF_DST], npf_nat_gettrans_addr(con->c_nat)->word32[0], (uint16_t)npf_nat_gettrans_port(con->c_nat)); + } } if (con->c_rproc) { /* Release the rule procedure. */ @@ -555,7 +558,7 @@ npf_conn_setnat(const npf_cache_t *npc, npf_conn_t *con, npf_conn_t *ret __diagused; npf_addr_t *taddr; in_port_t tport; - unsigned alen; + uint16_t alen; KASSERT(con->c_refcnt > 0); @@ -614,16 +617,19 @@ npf_conn_setnat(const npf_cache_t *npc, npf_conn_t *con, mutex_exit(&con->c_lock); /* NAT events: execute create ipv4 translation callback */ - if (alen == NPF_IPV4_ALEN && - npf->nat_events_opts.ipv4_create_translation != NULL) + if (alen == sizeof(in_addr_t) && + npf->nat_events_opts.ipv4_create_translation != NULL) { + uint16_t proto; + uint16_t ids[2]; + npf_addr_t ips[2]; + + npf_connkey_getkey(fw, &proto, ips, ids, &alen); npf->nat_events_opts.ipv4_create_translation( - npf_conn_key_get_proto(fw), - npf_conn_key_ipv4_get_src_addr(fw), - npf_conn_key_ipv4_get_src_id(fw), - npf_conn_key_ipv4_get_dst_addr(fw), - npf_conn_key_ipv4_get_dst_id(fw), + proto, ips[NPF_SRC].word32[0], ips[NPF_DST].word32[0], + ids[NPF_SRC], ids[NPF_DST], npf_nat_gettrans_addr(con->c_nat)->word32[0], (uint16_t)npf_nat_gettrans_port(con->c_nat)); + } return 0; } diff --git a/src/kern/npf_conn.h b/src/kern/npf_conn.h index fd3e2f08..b089cbe2 100644 --- a/src/kern/npf_conn.h +++ b/src/kern/npf_conn.h @@ -103,9 +103,6 @@ struct npf_conn { #define NPF_CONNKEY_ALEN(key) ((key)->ck_key[0] & 0xffff) #define NPF_CONNKEY_LEN(key) (8 + (NPF_CONNKEY_ALEN(key) * 2)) -#define NPF_IPV4_ALEN 4 -#define NPF_IPV6_ALEN 16 - struct npf_connkey { /* Warning: ck_key has a variable length -- see above. */ uint32_t ck_key[NPF_CONNKEY_MAXWORDS]; @@ -116,13 +113,6 @@ npf_connkey_t * npf_conn_getforwkey(npf_conn_t *); npf_connkey_t * npf_conn_getbackkey(npf_conn_t *, unsigned); void npf_conn_adjkey(npf_connkey_t *, const npf_addr_t *, const uint16_t, const int); - -uint16_t npf_conn_key_get_proto(const npf_connkey_t *); -uint16_t npf_conn_key_ipv4_get_src_id(const npf_connkey_t *); -uint16_t npf_conn_key_ipv4_get_dst_id(const npf_connkey_t *); -uint32_t npf_conn_key_ipv4_get_src_addr(const npf_connkey_t *); -uint32_t npf_conn_key_ipv4_get_dst_addr(const npf_connkey_t *); - unsigned npf_connkey_import(const nvlist_t *, npf_connkey_t *); nvlist_t * npf_connkey_export(const npf_connkey_t *); void npf_connkey_print(const npf_connkey_t *); diff --git a/src/kern/npf_connkey.c b/src/kern/npf_connkey.c index b48c6714..19a90359 100644 --- a/src/kern/npf_connkey.c +++ b/src/kern/npf_connkey.c @@ -66,36 +66,6 @@ __KERNEL_RCSID(0, "$NetBSD$"); #include "npf_conn.h" #include "npf_impl.h" -uint16_t -npf_conn_key_get_proto(const npf_connkey_t *key) -{ - return (uint16_t) (key->ck_key[0] >> 16); -} - -uint16_t -npf_conn_key_ipv4_get_src_id(const npf_connkey_t *key) -{ - return (uint16_t) (key->ck_key[1] >> 16); -} - -uint16_t -npf_conn_key_ipv4_get_dst_id(const npf_connkey_t *key) -{ - return (uint16_t) (key->ck_key[1] & 0xFFFF); -} - -uint32_t -npf_conn_key_ipv4_get_src_addr(const npf_connkey_t *key) -{ - return key->ck_key[2]; -} - -uint32_t -npf_conn_key_ipv4_get_dst_addr(const npf_connkey_t *key) -{ - return key->ck_key[3]; -} - static inline unsigned connkey_setkey(npf_connkey_t *key, uint16_t proto, const void *ipv, const uint16_t *id, unsigned alen, bool forw) diff --git a/src/kern/npfkern.h b/src/kern/npfkern.h index dabb5221..4a3a54b3 100644 --- a/src/kern/npfkern.h +++ b/src/kern/npfkern.h @@ -63,11 +63,11 @@ typedef struct { /* NAT event callbacks */ typedef void (*npf_nat_event_ipv4_create_translation_t) (uint16_t proto, - uint32_t src, uint16_t src_id, uint32_t dst, uint16_t dst_id, + uint32_t src, uint32_t dst, uint16_t src_id, uint16_t dst_id, uint32_t tsrc, uint16_t tsrc_id); typedef void (*npf_nat_event_ipv4_destroy_translation_t) (uint16_t proto, - uint32_t src, uint16_t src_id, uint32_t dst, uint16_t dst_id, + uint32_t src, uint32_t dst, uint16_t src_id, uint16_t dst_id, uint32_t tsrc, uint16_t tsrc_id); typedef struct { From 617d7cd59883a7775eefefb1293ce7699c811a21 Mon Sep 17 00:00:00 2001 From: "kiselev99@gmail.com" Date: Thu, 25 Jul 2019 19:09:32 +0300 Subject: [PATCH 3/3] styling --- src/kern/npf_impl.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/kern/npf_impl.h b/src/kern/npf_impl.h index 109829d7..8c8e8b62 100644 --- a/src/kern/npf_impl.h +++ b/src/kern/npf_impl.h @@ -202,7 +202,7 @@ struct npf { /* BPF byte-code context. */ bpf_ctx_t * bpfctx; const npf_mbufops_t * mbufops; - + /* Parameters. */ npf_paraminfo_t * paraminfo; void * params[NPF_PARAMS_COUNT]; @@ -239,7 +239,7 @@ struct npf { percpu_t * stats_percpu; /* NAT events callbacks */ - npf_nat_events_ops_t nat_events_opts; + npf_nat_events_ops_t nat_events_opts; }; /*