Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 35 additions & 2 deletions src/kern/npf_conn.c
Original file line number Diff line number Diff line change
Expand Up @@ -500,14 +500,29 @@ 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);

if (con->c_nat) {
/* Release any NAT structures. */
npf_nat_destroy(con->c_nat);

/* NAT events: execute destroy ipv4 translation callback */
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(
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. */
Expand Down Expand Up @@ -543,6 +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;
uint16_t alen;

KASSERT(con->c_refcnt > 0);

Expand Down Expand Up @@ -572,7 +588,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);

Expand All @@ -598,6 +615,22 @@ 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 == 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(
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;
}

Expand Down
1 change: 0 additions & 1 deletion src/kern/npf_conn.h
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +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);

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 *);
Expand Down
5 changes: 5 additions & 0 deletions src/kern/npf_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,9 @@ struct npf {

/* Statistics. */
percpu_t * stats_percpu;

/* NAT events callbacks */
npf_nat_events_ops_t nat_events_opts;
};

/*
Expand Down Expand Up @@ -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 *);
Expand Down
26 changes: 26 additions & 0 deletions src/kern/npf_nat.c
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*/
Expand Down Expand Up @@ -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;
}
20 changes: 20 additions & 0 deletions src/kern/npfkern.h
Original file line number Diff line number Diff line change
Expand Up @@ -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, 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, uint32_t dst, uint16_t src_id, 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);

Expand All @@ -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