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
| | /* SPDX-License-Identifier: GPL-2.0-or-later
* Copyright Red Hat
* Author: David Gibson <david@gibson.dropbear.id.au>
*
* Tracking for logical "flows" of packets.
*/
#ifndef FLOW_H
#define FLOW_H
enum flow_type {
FLOW_NONE = 0,
FLOW_TCP,
FLOW_TCP_SPLICE,
FLOW_MAX = FLOW_TCP_SPLICE,
};
extern const char *flow_type_str[];
#define FLOW_TYPE(f) \
((f)->type <= FLOW_MAX ? flow_type_str[(f)->type] : "?")
/**
* struct flowside - Describes a logical packet flow as seen from one "side"
* @eaddr: Endpoint address (remote address from passt's PoV)
* @faddr: Forwarding address (local address from passt's PoV)
* @eport: Endpoint port
* @fport: Forwarding port
*/
struct flowside {
union inany_addr faddr;
union inany_addr eaddr;
in_port_t fport, eport;
};
/** flowside_from_af - Initialize a flowside from addresses
* @fs: flowside to initialize
* @af: Address family (AF_INET or AF_INET6)
* @faddr: Forwarding address (pointer to in_addr or in6_addr)
* @fport: Forwarding port
* @eaddr: Endpoint address (pointer to in_addr or in6_addr)
* @eport: Endpoint port
*/
static inline void flowside_from_af(struct flowside *fs, int af,
const void *faddr, in_port_t fport,
const void *eaddr, in_port_t eport)
{
inany_from_af(&fs->faddr, af, faddr);
inany_from_af(&fs->eaddr, af, eaddr);
fs->fport = fport;
fs->eport = eport;
}
/** flowside_complete - Check if flowside is fully initialized
* @fs: flowside to check
*/
static inline bool flowside_complete(const struct flowside *fs)
{
return !IN6_IS_ADDR_UNSPECIFIED(&fs->faddr) &&
!IN6_IS_ADDR_UNSPECIFIED(&fs->eaddr) &&
fs->fport != 0 && fs->eport != 0;
}
#define FLOWSIDE_STRLEN (2*(INET6_ADDRSTRLEN+8) + 6)
const char *flowside_fmt(const struct flowside *fs, char *buf, size_t size);
/**
* flowside_eq() - Check if two flowsides are equal
* @left, @right: Flowsides to compare
*
* Return: true if equal, false otherwise
*/
static inline bool flowside_eq(const struct flowside *left,
const struct flowside *right)
{
return memcmp(left, right, sizeof(struct flowside)) == 0;
}
/**
* flowside_hash() - Calculate hash value for a flowside
* @fs: Flowside
* @k: Hash secret (128-bits as array of 2 64-bit words)
*
* Return: hash value
*/
static inline unsigned int flowside_hash(const struct flowside *fs,
const uint64_t *k)
{
ASSERT(flowside_complete(fs));
return siphash_36b((uint8_t *)fs, k);
}
/**
* struct flow_common - Common fields for packet flows
* @side[]: Information on the flow for each side. Flow types can have
* their own conventions about which side is which
* @type: Type of packet flow
*/
struct flow_common {
struct flowside side[2];
enum flow_type type;
};
#define FLOW_INDEX_BITS 17 /* 128k - 1 */
#define FLOW_MAX MAX_FROM_BITS(FLOW_INDEX_BITS)
#define FLOW_TABLE_PRESSURE 30 /* % of FLOW_MAX */
#define FLOW_FILE_PRESSURE 30 /* % of c->nofile */
union flow;
void flow_table_compact(struct ctx *c, union flow *hole);
#endif /* FLOW_H */
|