L4Re Operating System Framework
Interface and Usage Documentation
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
port.h
1/*
2 * Copyright (C) 2016-2018, 2020, 2022-2024 Kernkonzept GmbH.
3 * Author(s): Jean Wolter <jean.wolter@kernkonzept.com>
4 * Alexander Warg <warg@os.inf.tu-dresden.de>
5 *
6 * License: see LICENSE.spdx (in this directory or the directories above)
7 */
8#pragma once
9
10#include "request.h"
11#include "mac_addr.h"
12#include "vlan.h"
13#include "stats.h"
14
15#include <cassert>
16#include <set>
17#include <vector>
18
24class Port_iface
25{
26protected:
27 Virtio_net_switch::Port_statistics *_stats;
28
29public:
30 Port_iface(char const *name)
31 {
32 strncpy(_name, name, sizeof(_name));
33 _name[sizeof(_name) - 1] = '\0';
34#ifdef CONFIG_VNS_STATS
35 _stats = Switch_statistics::get_instance().allocate_port_statistics(name);
36 if (!_stats)
38 "Could not allocate port statistics.\n");
39#endif
40 }
41
42 virtual ~Port_iface()
43 {
44#ifdef CONFIG_VNS_STATS
45 _stats->in_use = false;
46#endif
47 }
48
49 // delete copy and assignment
50 Port_iface(Port_iface const &) = delete;
51 Port_iface &operator = (Port_iface const &) = delete;
52
53 char const *get_name() const
54 { return _name; }
55
56 l4_uint16_t get_vlan() const
57 { return _vlan_id; }
58
59 inline bool is_trunk() const
60 { return _vlan_id == VLAN_ID_TRUNK; }
61
62 inline bool is_native() const
63 { return _vlan_id == VLAN_ID_NATIVE; }
64
65 inline bool is_access() const
66 { return !is_trunk() && !is_native(); }
67
75 void set_vlan_access(l4_uint16_t id)
76 {
77 assert(vlan_valid_id(id));
78 _vlan_id = id;
79 _vlan_bloom_filter = 0;
80 _vlan_ids.clear();
81 }
82
92 void set_vlan_trunk(const std::vector<l4_uint16_t> &ids)
93 {
94 // bloom filter to quickly reject packets that do not belong to this port
95 l4_uint32_t filter = 0;
96
97 _vlan_ids.clear();
98 for (const auto id : ids)
99 {
100 assert(vlan_valid_id(id));
101 filter |= vlan_bloom_hash(id);
102 _vlan_ids.insert(id);
103 }
104
105 _vlan_id = VLAN_ID_TRUNK;
106 _vlan_bloom_filter = filter;
107 }
108
112 void set_vlan_trunk_all()
113 {
114 _vlan_all = true;
115 _vlan_id = VLAN_ID_TRUNK;
116 _vlan_bloom_filter = -1;
117 }
118
125 void set_monitor()
126 {
127 _vlan_id = VLAN_ID_TRUNK;
128 _vlan_bloom_filter = 0;
129 }
130
139 bool match_vlan(uint16_t id)
140 {
141 // Regular case native/access port
142 if (id == _vlan_id)
143 return true;
144
145 // This port participates in all VLANs
146 if (_vlan_all)
147 return true;
148
149 // Quick check: does port probably accept this VLAN?
150 if ((_vlan_bloom_filter & vlan_bloom_hash(id)) == 0)
151 return false;
152
153 return _vlan_ids.find(id) != _vlan_ids.end();
154 }
155
162 inline Mac_addr mac() const
163 { return _mac; }
164
165 Virtio_vlan_mangle create_vlan_mangle(Port_iface *src_port) const
166 {
167 Virtio_vlan_mangle mangle;
168
169 if (is_trunk())
170 {
171 /*
172 * Add a VLAN tag only if the packet does not already have one (by
173 * coming from another trunk port) or if the packet does not belong to
174 * any VLAN (by coming from a native port). The latter case is only
175 * relevant if this is a monitor port. Otherwise traffic from native
176 * ports is never forwarded to trunk ports.
177 */
178 if (!src_port->is_trunk() && !src_port->is_native())
179 mangle = Virtio_vlan_mangle::add(src_port->get_vlan());
180 }
181 else
182 /*
183 * Remove VLAN tag only if the packet actually has one (by coming from a
184 * trunk port).
185 */
186 if (src_port->is_trunk())
188
189 return mangle;
190 }
191
192 virtual void rx_notify_disable_and_remember() = 0;
193 virtual void rx_notify_emit_and_enable() = 0;
194
195 virtual bool is_gone() const = 0;
196
198 // std::optional<Net_request> get_tx_request() = 0;
199
200 enum class Result
201 {
202 Delivered, Exception, Dropped,
203 };
204
220 virtual Result handle_request(Port_iface *src_port,
221 Net_transfer &src,
222 l4_uint64_t *bytes_transferred) = 0;
223
224 void reschedule_pending_tx()
225 { _pending_tx_reschedule->trigger(); }
226
227protected:
228 /*
229 * VLAN related management information.
230 *
231 * A port may either be
232 * - a native port (_vlan_id == VLAN_ID_NATIVE), or
233 * - an access port (_vlan_id set accordingly), or
234 * - a trunk port (_vlan_id == VLAN_ID_TRUNK, _vlan_bloom_filter and
235 * _vlan_ids populated accordingly, or _vlan_all == true).
236 */
237 l4_uint16_t _vlan_id = VLAN_ID_NATIVE; // VID for native/access port
238 l4_uint32_t _vlan_bloom_filter = 0; // Bloom filter for trunk ports
239 std::set<l4_uint16_t> _vlan_ids; // Authoritative list of trunk VLANs
240 bool _vlan_all; // This port participates in all VLANs (ignoring _vlan_ids)
241
242 inline l4_uint32_t vlan_bloom_hash(l4_uint16_t vid)
243 { return 1UL << (vid & 31U); }
244
248 L4::Cap<L4::Irq> _pending_tx_reschedule;
249
250 Mac_addr _mac = Mac_addr(Mac_addr::Addr_unknown);
251 char _name[20];
253public:
254#ifdef CONFIG_VNS_STATS
255 inline void stat_inc_tx_num()
256 { _stats->tx_num++; }
257 inline void stat_inc_tx_dropped()
258 { _stats->tx_dropped++; }
259 inline void stat_inc_tx_bytes(l4_uint64_t bytes)
260 { _stats->tx_bytes += bytes; }
261 inline void stat_inc_rx_num()
262 { _stats->rx_num++; }
263 inline void stat_inc_rx_dropped()
264 { _stats->rx_dropped++; }
265 inline void stat_inc_rx_bytes(l4_uint64_t bytes)
266 { _stats->rx_bytes += bytes; }
267#else
268 inline void stat_inc_tx_num()
269 {}
270 inline void stat_inc_tx_dropped()
271 {}
272 inline void stat_inc_tx_bytes(l4_uint64_t /*bytes*/)
273 {}
274 inline void stat_inc_rx_num()
275 {}
276 inline void stat_inc_rx_dropped()
277 {}
278 inline void stat_inc_rx_bytes(l4_uint64_t /*bytes*/)
279 {}
280#endif
281};
282
C++ interface for capabilities.
Definition capability.h:224
Exception for an abstract runtime error.
Definition exceptions:129
A wrapper class around the value of a MAC address.
Definition mac_addr.h:20
A network request to only a single destination.
Definition request.h:34
Class for VLAN packet rewriting.
Definition vlan.h:37
static constexpr Virtio_vlan_mangle remove()
Construct an object that removes the VLAN tag.
Definition vlan.h:75
static constexpr Virtio_vlan_mangle add(l4_uint16_t tci)
Construct an object that adds a VLAN tag.
Definition vlan.h:64
unsigned int l4_uint32_t
Unsigned 32bit value.
Definition l4int.h:29
unsigned short int l4_uint16_t
Unsigned 16bit value.
Definition l4int.h:27
unsigned long long l4_uint64_t
Unsigned 64bit value.
Definition l4int.h:31
@ L4_ENOMEM
No memory.
Definition err.h:39