aboutsummaryrefslogtreecommitdiffstats
path: root/driver/allowedips.h
blob: 0e17b9270d38fcb739bc90ef0c1884631a95b432 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
/* SPDX-License-Identifier: GPL-2.0
 *
 * Copyright (C) 2015-2021 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
 */

#pragma once

#include "rcu.h"
#include "arithmetic.h"
#include <ntifs.h> /* Must be included before <wdm.h> */
#include <wdm.h>
#include <wsk.h>

typedef struct _WG_PEER WG_PEER;

typedef struct _ALLOWEDIPS_NODE ALLOWEDIPS_NODE;
struct _ALLOWEDIPS_NODE
{
    WG_PEER __rcu *Peer;
    ALLOWEDIPS_NODE __rcu *Bit[2];
    UINT8 Cidr, BitAtA, BitAtB, Bitlen;
    __declspec(align(8)) UINT8 Bits[16];

    /* Keep rarely used members at bottom to be beyond cache line. */
    ULONG_PTR ParentBitPacked;
    union
    {
        LIST_ENTRY PeerList;
        RCU_CALLBACK Rcu;
    };
};

typedef __declspec(align(4)) struct _ALLOWEDIPS_TABLE
{
    ALLOWEDIPS_NODE __rcu *Root4;
    ALLOWEDIPS_NODE __rcu *Root6;
    UINT64 Seq;
} ALLOWEDIPS_TABLE;

VOID
AllowedIpsInit(_Out_ ALLOWEDIPS_TABLE *Table);

_Requires_lock_held_(Lock)
VOID
AllowedIpsFree(_Inout_ ALLOWEDIPS_TABLE *Table, _In_ EX_PUSH_LOCK *Lock);

_Requires_lock_held_(Lock)
NTSTATUS
AllowedIpsInsertV4(
    _Inout_ ALLOWEDIPS_TABLE *Table,
    _In_ CONST IN_ADDR *Ip,
    _In_ UINT8 Cidr,
    _In_ WG_PEER *Peer,
    _In_ EX_PUSH_LOCK *Lock);

_Requires_lock_held_(Lock)
NTSTATUS
AllowedIpsInsertV6(
    _Inout_ ALLOWEDIPS_TABLE *Table,
    _In_ CONST IN6_ADDR *Ip,
    _In_ UINT8 Cidr,
    _In_ WG_PEER *Peer,
    _In_ EX_PUSH_LOCK *Lock);

_Requires_lock_held_(Lock)
VOID
AllowedIpsRemoveByPeer(_Inout_ ALLOWEDIPS_TABLE *Table, _In_ WG_PEER *Peer, _In_ EX_PUSH_LOCK *Lock);

/* The Ip pointer should be 8 byte aligned */
ADDRESS_FAMILY
AllowedIpsReadNode(_In_ CONST ALLOWEDIPS_NODE *Node, _Out_ UINT8 Ip[16], _Out_ UINT8 *Cidr);

/* These return a strong reference to a peer: */
_Must_inspect_result_
_Post_maybenull_
WG_PEER *
AllowedIpsLookupDst(_In_ ALLOWEDIPS_TABLE *Table, _In_ UINT16_BE Proto, _In_ CONST VOID *IpHdr);

_Must_inspect_result_
_Post_maybenull_
WG_PEER *
AllowedIpsLookupSrc(_In_ ALLOWEDIPS_TABLE *Table, _In_ UINT16_BE Proto, _In_ CONST VOID *IpHdr);

#ifdef DBG
_IRQL_requires_max_(PASSIVE_LEVEL)
BOOLEAN
AllowedIpsSelftest(VOID);
#endif

_IRQL_requires_max_(DISPATCH_LEVEL)
NTSTATUS
AllowedIpsDriverEntry(VOID);

_IRQL_requires_max_(APC_LEVEL)
VOID AllowedIpsUnload(VOID);