summaryrefslogtreecommitdiff
path: root/lib/ct-dpif.h
blob: d5f966175bc00e851470a166fd97f0c83316c956 (plain)
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
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
/*
 * Copyright (c) 2015 Nicira, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at:
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef CT_DPIF_H
#define CT_DPIF_H

#include "openvswitch/types.h"
#include "packets.h"

union ct_dpif_inet_addr {
    ovs_be32 ip;
    ovs_be32 ip6[4];
    struct in_addr in;
    struct in6_addr in6;
};

struct ct_dpif_tuple {
    uint16_t l3_type; /* Address family. */
    uint8_t  ip_proto;
    union ct_dpif_inet_addr src;
    union ct_dpif_inet_addr dst;
    union {
        ovs_be16 src_port;
        ovs_be16 icmp_id;
    };
    union {
        ovs_be16 dst_port;
        struct {
            uint8_t icmp_type;
            uint8_t icmp_code;
        };
    };
};
BUILD_ASSERT_DECL(sizeof(struct ct_dpif_tuple) % 8 == 0);

struct ct_dpif_counters {
    uint64_t packets;
    uint64_t bytes;
};

/* Nanoseconds from January 1, 1970 */
struct ct_dpif_timestamp {
    /* When the entry was created */
    uint64_t start;
    /* When the entry was deleted */
    uint64_t stop;
};

#define CT_DPIF_TCP_STATES \
    CT_DPIF_TCP_STATE(CLOSED) \
    CT_DPIF_TCP_STATE(LISTEN) \
    CT_DPIF_TCP_STATE(SYN_SENT) \
    CT_DPIF_TCP_STATE(SYN_RECV) \
    CT_DPIF_TCP_STATE(ESTABLISHED) \
    CT_DPIF_TCP_STATE(CLOSE_WAIT) \
    CT_DPIF_TCP_STATE(FIN_WAIT_1) \
    CT_DPIF_TCP_STATE(CLOSING) \
    CT_DPIF_TCP_STATE(LAST_ACK) \
    CT_DPIF_TCP_STATE(FIN_WAIT_2) \
    CT_DPIF_TCP_STATE(TIME_WAIT) \
    CT_DPIF_TCP_STATE(MAX_NUM)

enum ct_dpif_tcp_state {
#define CT_DPIF_TCP_STATE(STATE) CT_DPIF_TCPS_##STATE,
    CT_DPIF_TCP_STATES
#undef CT_DPIF_TCP_STATE
};

extern const char *ct_dpif_tcp_state_string[];

#define CT_DPIF_TCP_FLAGS \
    CT_DPIF_TCP_FLAG(WINDOW_SCALE) \
    CT_DPIF_TCP_FLAG(SACK_PERM) \
    CT_DPIF_TCP_FLAG(CLOSE_INIT) \
    CT_DPIF_TCP_FLAG(BE_LIBERAL) \
    CT_DPIF_TCP_FLAG(DATA_UNACKNOWLEDGED) \
    CT_DPIF_TCP_FLAG(MAXACK_SET) \

enum ct_dpif_tcp_flags_count_ {
#define CT_DPIF_TCP_FLAG(FLAG) FLAG##_COUNT_,
    CT_DPIF_TCP_FLAGS
#undef CT_DPIF_TCP_FLAG
};

enum ct_dpif_tcp_flags {
#define CT_DPIF_TCP_FLAG(FLAG) CT_DPIF_TCPF_##FLAG = (1 << FLAG##_COUNT_),
    CT_DPIF_TCP_FLAGS
#undef CT_DPIF_TCP_FLAG
};

struct ct_dpif_protoinfo {
    uint16_t proto; /* IPPROTO_* */
    union {
        struct {
            uint8_t state_orig;
            uint8_t state_reply;
            uint8_t wscale_orig;
            uint8_t wscale_reply;
            uint8_t flags_orig;
            uint8_t flags_reply;
        } tcp;
    };
};

struct ct_dpif_helper {
    char *name;
};

#define CT_DPIF_STATUS_FLAGS \
    CT_DPIF_STATUS_FLAG(EXPECTED) \
    CT_DPIF_STATUS_FLAG(SEEN_REPLY) \
    CT_DPIF_STATUS_FLAG(ASSURED) \
    CT_DPIF_STATUS_FLAG(CONFIRMED) \
    CT_DPIF_STATUS_FLAG(SRC_NAT) \
    CT_DPIF_STATUS_FLAG(DST_NAT) \
    CT_DPIF_STATUS_FLAG(SEQ_ADJUST) \
    CT_DPIF_STATUS_FLAG(SRC_NAT_DONE) \
    CT_DPIF_STATUS_FLAG(DST_NAT_DONE) \
    CT_DPIF_STATUS_FLAG(DYING) \
    CT_DPIF_STATUS_FLAG(FIXED_TIMEOUT) \
    CT_DPIF_STATUS_FLAG(TEMPLATE) \
    CT_DPIF_STATUS_FLAG(UNTRACKED) \

enum ct_dpif_status_flags_count_ {
#define CT_DPIF_STATUS_FLAG(FLAG) FLAG##_COUNT_,
    CT_DPIF_STATUS_FLAGS
#undef CT_DPIF_STATUS_FLAG
};

enum ct_dpif_status_flags {
#define CT_DPIF_STATUS_FLAG(FLAG) CT_DPIF_STATUS_##FLAG = (1 << FLAG##_COUNT_),
    CT_DPIF_STATUS_FLAGS
#undef CT_DPIF_STATUS_FLAG
};

struct ct_dpif_entry {
    /* Const members. */
    struct ct_dpif_tuple tuple_orig;
    struct ct_dpif_tuple tuple_reply;
    struct ct_dpif_tuple tuple_master;
    struct ct_dpif_helper helper;
    uint32_t id;
    uint16_t zone;

    /* Modifiable members. */

    struct ct_dpif_counters counters_orig;
    struct ct_dpif_counters counters_reply;

    struct ct_dpif_timestamp timestamp;
    struct ct_dpif_protoinfo protoinfo;

    ovs_u128 labels;
    bool have_labels;
    uint32_t status;
    /* Timeout for this entry in seconds */
    uint32_t timeout;
    uint32_t mark;
    uint32_t bkt;       /* CT bucket number. */
};

enum {
    CT_STATS_UDP,
    CT_STATS_TCP,
    CT_STATS_SCTP,
    CT_STATS_ICMP,
    CT_STATS_ICMPV6,
    CT_STATS_UDPLITE,
    CT_STATS_DCCP,
    CT_STATS_IGMP,
    CT_STATS_OTHER,
    CT_STATS_MAX,
};

struct dpif;

struct ct_dpif_dump_state {
    struct dpif *dpif;
};

int ct_dpif_dump_start(struct dpif *, struct ct_dpif_dump_state **,
                       const uint16_t *zone, int *);
int ct_dpif_dump_next(struct ct_dpif_dump_state *, struct ct_dpif_entry *);
int ct_dpif_dump_done(struct ct_dpif_dump_state *);
int ct_dpif_flush(struct dpif *, const uint16_t *zone);
void ct_dpif_entry_uninit(struct ct_dpif_entry *);
void ct_dpif_format_entry(const struct ct_dpif_entry *, struct ds *,
                          bool verbose, bool print_stats);
void ct_dpif_format_tuple(struct ds *, const struct ct_dpif_tuple *);
uint8_t ct_dpif_coalesce_tcp_state(uint8_t state);
void ct_dpif_format_tcp_stat(struct ds *, int, int);

#endif /* CT_DPIF_H */