-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathworker.h
211 lines (183 loc) · 5.95 KB
/
worker.h
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
207
208
209
210
211
/* SPDX-License-Identifier: BSD-3-Clause
* Copyright (c) 2021 ETH Zurich
*/
#ifndef LF_WORKER_H
#define LF_WORKER_H
#include <inttypes.h>
#include <rte_common.h>
#include <rte_ether.h>
#include <rte_ip.h>
#include <rte_lcore.h>
#include <rte_mbuf.h>
#include <rte_mempool.h>
#include "config.h"
#include "keymanager.h"
#include "lf.h"
#include "lib/crypto/crypto.h"
#include "lib/log/log.h"
#include "lib/mirror/mirror.h"
#include "lib/time/time.h"
#include "ratelimiter.h"
/**
* The worker implements the LightningFilter pipeline and processes packets
* (inbound as well as outbound).
*/
/**
* Log function for LF worker.
* The lcore ID is added to each message. Format with lcore ID 1:
* Worker [1]: log message here
*/
#define LF_WORKER_LOG(level, ...) \
LF_LOG(level, RTE_FMT("Worker [%d]: " RTE_FMT_HEAD(__VA_ARGS__, ), \
rte_lcore_id(), RTE_FMT_TAIL(__VA_ARGS__, )))
#define LF_WORKER_LOG_DP(level, ...) \
LF_LOG_DP(level, RTE_FMT("Worker [%d]: " RTE_FMT_HEAD(__VA_ARGS__, ), \
rte_lcore_id(), RTE_FMT_TAIL(__VA_ARGS__, )))
struct lf_worker_context {
uint16_t lcore_id;
/* RX/TX ports and queues */
/* TODO: remove from the lf worker context */
uint16_t max_rx_tx_index, current_rx_tx_index;
uint16_t rx_port_id[RTE_MAX_ETHPORTS];
uint16_t rx_queue_id[RTE_MAX_ETHPORTS];
uint16_t tx_port_id[RTE_MAX_ETHPORTS];
uint16_t tx_queue_id[RTE_MAX_ETHPORTS];
uint16_t tx_queue_id_by_port[RTE_MAX_ETHPORTS];
struct rte_eth_dev_tx_buffer *tx_buffer[RTE_MAX_ETHPORTS];
struct rte_eth_dev_tx_buffer *tx_buffer_by_port[RTE_MAX_ETHPORTS];
/* Forwarding port pair */
/* TODO: replace with a ip lookup struct for proper l3 forwarding */
uint16_t port_pair[RTE_MAX_ETHPORTS];
/* Timestamp threshold in nanoseconds */
uint64_t timestamp_threshold;
/*
* Worker contexts of the different modules
*/
struct lf_configmanager_worker *config;
struct lf_keymanager_worker *key_manager;
struct lf_duplicate_filter_worker *duplicate_filter;
struct lf_ratelimiter_worker ratelimiter;
struct lf_statistics_worker *statistics;
struct lf_time_worker time;
struct lf_crypto_hash_ctx crypto_hash_ctx;
struct lf_crypto_drkey_ctx crypto_drkey_ctx;
struct lf_mirror_worker *mirror_ctx;
/* Quiescent State Variable */
struct rte_rcu_qsbr *qsv;
unsigned int qsv_id;
} __rte_cache_aligned;
/**
* Summary of data contained in a packet that is required by LightningFilter.
* This includes addresses, timestamp, DRKey protocol number, MAC, etc..
*/
struct lf_pkt_data {
/* Peer/Source ISD AS number (network byte order). */
uint64_t src_as;
/* Destination ISD AS number (network byte order). */
uint64_t dst_as;
/* Peer/Source host address with length/type and pointer to
* address (network byte order). */
struct lf_host_addr src_addr;
/* Destination host address with length/type and pointer to
* address (network byte order). */
struct lf_host_addr dst_addr;
/* Packet timestamp: Unix epoch in nanoseconds */
uint64_t timestamp;
/* DRKey Protocol number (network byte order). */
uint16_t drkey_protocol;
/* LF_CRYPTO_MAC_SIZE bytes of MAC */
uint8_t *mac;
/* LF_CRYPTO_MAC_DATA_SIZE bytes of authenticated data, i.e., input for MAC
* calculation. */
uint8_t *auth_data;
/* Packet length for rate limiting. */
uint32_t pkt_len;
};
/**
* The action to be performed with the packet.
*/
enum lf_pkt_action {
LF_PKT_UNKNOWN = 0,
LF_PKT_UNKNOWN_DROP,
LF_PKT_UNKNOWN_FORWARD,
LF_PKT_OUTBOUND_DROP,
LF_PKT_OUTBOUND_FORWARD,
LF_PKT_INBOUND_DROP,
LF_PKT_INBOUND_FORWARD,
};
/**
* The packet check can provide following results.
*/
enum lf_check_state {
LF_CHECK_ERROR,
LF_CHECK_NO_HEADER,
LF_CHECK_NO_KEY,
LF_CHECK_INVALID_MAC,
LF_CHECK_OUTDATED_TIMESTAMP,
LF_CHECK_DUPLICATE,
LF_CHECK_AS_RATELIMITED,
LF_CHECK_SYSTEM_RATELIMITED,
LF_CHECK_VALID_MAC_BUT_INVALID_HASH,
LF_CHECK_VALID, /* Valid Packet */
LF_CHECK_BE_RATELIMITED,
LF_CHECK_BE, /* Best-Effort Packet */
};
/**
* Reset all worker contexts for all lcores that run a worker. All fields but
* the lcore_id field are set to 0. The lcore_id field is set approapriately.
*
* @param worker_lcores The lcore boolean map for workers, that indicates which
* cores run a worker.
* @param worker_contexts Array of worker contexts.
* @return 0 on success.
*/
int
lf_worker_init(bool worker_lcores[RTE_MAX_LCORE],
struct lf_worker_context worker_contexts[RTE_MAX_LCORE]);
/**
* Launch function for the workers.
* @param worker_context The worker context.
* @return Returns 0.
*/
int
lf_worker_run(struct lf_worker_context *worker_context);
/**
* Parse the packet and decide wether to forward it or to drop it.
*/
void
lf_worker_handle_pkt(struct lf_worker_context *worker_context,
struct rte_mbuf **pkt_burst, uint16_t nb_pkts,
enum lf_pkt_action *pkt_res);
/**
* Check if packet can pass as a valid packet.
* Therefore, this function verifies the MAC, checks the timestamp, applies
* duplicate filtering, and rate limiting.
*
* @param pkt_data Struct containing packet data to perform the checks.
* @return Result of the packet check
*/
enum lf_check_state
lf_worker_check_pkt(struct lf_worker_context *worker_context,
const struct lf_pkt_data *pkt_data);
/**
* Check if packet can pass as a best-effort packet.
* Therefore, this function applies rate limiting.
*
* @return enum lf_check_state.
*/
enum lf_check_state
lf_worker_check_best_effort_pkt(struct lf_worker_context *worker_context,
uint32_t pkt_len);
/**
* This function modifies the packet (ethernet and IP header) according the
* provided modifier and updates the checksum.
*
* @param ether_hdr Ethernet header to be modified. Can be NULL.
* @param l3_hdr pointer to l3 header. If LF_IPV6, "struct rte_ipv6_hdr *",
* otherwise, "struct rte_ipv4_hdr *".
* @param pkt_mod The packet modification configuration.
*/
void
lf_worker_pkt_mod(struct rte_mbuf *m, struct rte_ether_hdr *ether_hdr,
void *l3_hdr, const struct lf_config_pkt_mod *pkt_mod);
#endif /* LF_WORKER_H */