Skip to content

Commit 257d746

Browse files
authored
Merge pull request #1403 from AndreasAakesson/dev
Network stuff, NAT (WIP), (dont build)Solo5 on Mac
2 parents 017e938 + d50ca05 commit 257d746

23 files changed

Lines changed: 814 additions & 82 deletions

CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ set(CMAKE_C_COMPILER_TARGET ${TRIPLE})
1717

1818
message(STATUS "Target triple ${TRIPLE}")
1919

20+
option(WITH_SOLO5 "Install with solo5 support" ON)
21+
2022
set(CMAKE_TOOLCHAIN_FILE ${INCLUDEOS_ROOT}/cmake/${ARCH}-elf-toolchain.cmake)
2123

2224
project (includeos C CXX)

api/net/inet.hpp

Lines changed: 60 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020

2121
#include <chrono>
2222
#include <unordered_set>
23-
23+
#include <list>
2424
#include <net/inet_common.hpp>
2525
#include <hw/mac_addr.hpp>
2626
#include <hw/nic.hpp>
@@ -48,24 +48,25 @@ namespace net {
4848
using resolve_func = delegate<void(typename IPv::addr, Error&)>;
4949
using Vip_list = std::unordered_set<typename IPV::addr>;
5050

51+
5152
///
5253
/// NETWORK CONFIGURATION
5354
///
5455

5556
/** Get IP address of this interface **/
56-
virtual typename IPV::addr ip_addr() = 0;
57+
virtual typename IPV::addr ip_addr() const = 0;
5758

5859
/** Get netmask of this interface **/
59-
virtual typename IPV::addr netmask() = 0;
60+
virtual typename IPV::addr netmask() const = 0;
6061

6162
/** Get default gateway for this interface **/
62-
virtual typename IPV::addr gateway() = 0;
63+
virtual typename IPV::addr gateway() const = 0;
6364

6465
/** Get default dns for this interface **/
65-
virtual typename IPV::addr dns_addr() = 0;
66+
virtual typename IPV::addr dns_addr() const = 0;
6667

6768
/** Get broadcast address for this interface **/
68-
virtual typename IPV::addr broadcast_addr() = 0;
69+
virtual typename IPV::addr broadcast_addr() const = 0;
6970

7071
/** Set default gateway for this interface */
7172
virtual void set_gateway(typename IPV::addr server) = 0;
@@ -113,6 +114,55 @@ namespace net {
113114
virtual bool is_valid_source(typename IPV::addr) = 0;
114115

115116

117+
///
118+
/// PACKET FILTERING
119+
///
120+
121+
using Packetfilter = delegate<typename IPV::IP_packet_ptr(typename IPV::IP_packet_ptr, const Stack&)>;
122+
123+
struct Filter_chain {
124+
std::list<Packetfilter> chain;
125+
const char* name;
126+
127+
typename IPV::IP_packet_ptr operator()(typename IPV::IP_packet_ptr pckt, const Stack& stack) {
128+
int i = 0;
129+
for (auto filter : chain) {
130+
i++;
131+
pckt = filter(std::move(pckt), stack);
132+
if (pckt == nullptr) {
133+
debug("Packet dropped in %s chain, filter %i \n", name, i);
134+
// do some logging
135+
return nullptr;
136+
}
137+
}
138+
return pckt;
139+
}
140+
141+
Filter_chain(const char* chain_name, std::initializer_list<Packetfilter> filters) :
142+
chain{filters},
143+
name{chain_name} {}
144+
};
145+
146+
/**
147+
* Packet filtering hooks for firewall, NAT, connection tracking etc.
148+
**/
149+
150+
/** Packets pass through prerouting chain before routing decision */
151+
virtual Filter_chain& prerouting_chain() = 0;
152+
153+
/** Packets pass through postrouting chain after routing decision */
154+
virtual Filter_chain& postrouting_chain() = 0;
155+
156+
/** Packets pass through forward chain by forwarder, if enabled */
157+
virtual Filter_chain& forward_chain() = 0;
158+
159+
/** Packets pass through input chain before hitting protocol handlers */
160+
virtual Filter_chain& input_chain() = 0;
161+
162+
/** Packets pass through output chain after exiting protocol handlers */
163+
virtual Filter_chain& output_chain() = 0;
164+
165+
116166
///
117167
/// PROTOCOL OBJECTS
118168
///
@@ -166,7 +216,7 @@ namespace net {
166216
virtual std::string ifname() const = 0;
167217

168218
/** Get linklayer address for this interface **/
169-
virtual MAC::Addr link_addr() = 0;
219+
virtual MAC::Addr link_addr() const = 0;
170220

171221
/** Add cache entry to the link / IP address cache */
172222
virtual void cache_link_addr(typename IPV::addr, MAC::Addr) = 0;
@@ -182,7 +232,9 @@ namespace net {
182232
/// ROUTING
183233
///
184234

185-
/** Set an IP forwarding delegate. E.g. used to enable routing */
235+
/** Set an IP forwarding delegate. E.g. used to enable routing.
236+
* NOTE: The packet forwarder is expected to call the forward_chain
237+
**/
186238
virtual void set_forward_delg(Forward_delg) = 0;
187239

188240
/** Assign boolean function to determine if we have route to a given IP */

api/net/inet4.hpp

Lines changed: 34 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -43,25 +43,25 @@ namespace net {
4343
std::string ifname() const override
4444
{ return nic_.device_name(); }
4545

46-
MAC::Addr link_addr() override
46+
MAC::Addr link_addr() const override
4747
{ return nic_.mac(); }
4848

4949
hw::Nic& nic() override
5050
{ return nic_; }
5151

52-
IP4::addr ip_addr() override
52+
IP4::addr ip_addr() const override
5353
{ return ip4_addr_; }
5454

55-
IP4::addr netmask() override
55+
IP4::addr netmask() const override
5656
{ return netmask_; }
5757

58-
IP4::addr gateway() override
58+
IP4::addr gateway() const override
5959
{ return gateway_; }
6060

61-
IP4::addr dns_addr() override
61+
IP4::addr dns_addr() const override
6262
{ return dns_server_; }
6363

64-
IP4::addr broadcast_addr() override
64+
IP4::addr broadcast_addr() const override
6565
{ return ip4_addr_ | ( ~ netmask_); }
6666

6767
IP4& ip_obj() override
@@ -98,6 +98,7 @@ namespace net {
9898
/**
9999
* Set the forwarding delegate used by this stack.
100100
* If set it will get all incoming packets not intended for this stack.
101+
* NOTE: This delegate is expected to call the forward chain
101102
*/
102103
void set_forward_delg(Forward_delg fwd) override {
103104
ip4_.set_packet_forwarding(fwd);
@@ -306,6 +307,26 @@ namespace net {
306307
bool is_valid_source(IP4::addr src) override
307308
{ return is_loopback(src) or src == ip_addr(); }
308309

310+
/** Packets pass through prerouting chain before routing decision */
311+
virtual Filter_chain& prerouting_chain() override
312+
{ return prerouting_chain_; }
313+
314+
/** Packets pass through postrouting chain after routing decision */
315+
virtual Filter_chain& postrouting_chain() override
316+
{ return postrouting_chain_; }
317+
318+
/** Packets pass through postrouting chain after routing decision */
319+
virtual Filter_chain& forward_chain() override
320+
{ return forward_chain_; }
321+
322+
/** Packets pass through input chain before hitting protocol handlers */
323+
virtual Filter_chain& input_chain() override
324+
{ return input_chain_; }
325+
326+
/** Packets pass through output chain after exiting protocol handlers */
327+
virtual Filter_chain& output_chain() override
328+
{ return output_chain_; }
329+
309330
/** Initialize with ANY_ADDR */
310331
Inet4(hw::Nic& nic);
311332

@@ -330,6 +351,13 @@ namespace net {
330351
UDP udp_;
331352
TCP tcp_;
332353

354+
// Filter chains
355+
Filter_chain prerouting_chain_{"Prerouting", {}};
356+
Filter_chain postrouting_chain_{"Postrouting", {}};
357+
Filter_chain input_chain_{"Input", {}};
358+
Filter_chain output_chain_{"Output", {}};
359+
Filter_chain forward_chain_{"Forward", {}};
360+
333361
// we need this to store the cache per-stack
334362
DNSClient dns_;
335363
std::string domain_name_;

api/net/inet_common.hpp

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,38 @@ namespace net {
5353
return checksum(0, data, len);
5454
}
5555

56+
/**
57+
* @brief Adjust the checksum according to the difference between old and new data.
58+
*
59+
* @note Only supports even offsets (length needs to be even)
60+
* See: https://tools.ietf.org/html/rfc3022#page-9 (4.2) Checksum Adjustment
61+
*
62+
* @param chksum Pointer to the checksum to adjust
63+
* @param odata The old data
64+
* @param[in] olen The length of the old data
65+
* @param ndata The new data
66+
* @param[in] nlen The length of the new data
67+
*/
68+
void checksum_adjust(uint8_t* chksum, const void* odata,
69+
int olen, const void* ndata, int nlen);
70+
71+
/**
72+
* @brief Helper function for adjusting checksum when only an object is changed,
73+
* e.g. IP address in a packet header
74+
*
75+
* @param chksum Pointer to the checksum to adjust
76+
* @param[in] old_obj The old object
77+
* @param[in] new_obj The new object
78+
*
79+
* @tparam T The type of object
80+
*/
81+
template <typename T>
82+
void checksum_adjust(uint16_t* chksum, const T* old_obj, const T* new_obj)
83+
{
84+
static_assert(sizeof(T) % 2 == 0, "Checksum adjust only supports even lengths");
85+
checksum_adjust(reinterpret_cast<uint8_t*>(chksum), old_obj, sizeof(T), new_obj, sizeof(T));
86+
}
87+
5688
// View a packet differently based on context
5789
template <typename T, typename Packet>
5890
inline auto view_packet_as(Packet packet) noexcept {

api/net/ip4/ip4.hpp

Lines changed: 5 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,6 @@ namespace net {
4646
using IP_packet = PacketIP4;
4747
using IP_packet_ptr = std::unique_ptr<IP_packet>;
4848
using downstream_arp = delegate<void(Packet_ptr, IP4::addr)>;
49-
using Packet_filter = delegate<IP_packet_ptr(IP_packet_ptr)>;
5049
using drop_handler = delegate<void(IP_packet_ptr, Direction, Drop_reason)>;
5150
using PMTU = uint16_t;
5251

@@ -94,14 +93,6 @@ namespace net {
9493
void set_linklayer_out(downstream_arp s)
9594
{ linklayer_out_ = s; }
9695

97-
/** Assign function to determine which upstream packets gets filtered */
98-
void set_upstream_filter(Packet_filter f)
99-
{ upstream_filter_ = f; }
100-
101-
/** Assign function to determine which downstream packets gets filtered */
102-
void set_downstream_filter(Packet_filter f)
103-
{ downstream_filter_ = f; }
104-
10596
//
10697
// Delegate getters
10798
//
@@ -132,7 +123,7 @@ namespace net {
132123
* Source IP *can* be set - if it's not, IP4 will set it
133124
*/
134125
void transmit(Packet_ptr);
135-
void ship(Packet_ptr);
126+
void ship(Packet_ptr, addr next_hop = 0);
136127

137128

138129
/**
@@ -157,11 +148,11 @@ namespace net {
157148
uint64_t get_packets_dropped()
158149
{ return packets_dropped_; }
159150

160-
/** Default upstream packet filter */
161-
IP_packet_ptr filter_upstream(IP_packet_ptr packet);
151+
/** Drop incoming packets invalid according to RFC */
152+
IP_packet_ptr drop_invalid_in(IP_packet_ptr packet);
162153

163-
/** Default downstream packet filter */
164-
IP_packet_ptr filter_downstream(IP_packet_ptr packet);
154+
/** Drop outgoing packets invalid according to RFC */
155+
IP_packet_ptr drop_invalid_out(IP_packet_ptr packet);
165156

166157
/**
167158
* Path MTU (and Packetization Layered Path MTU Discovery) related methods
@@ -201,10 +192,6 @@ namespace net {
201192
/** Packet forwarding */
202193
Stack::Forward_delg forward_packet_;
203194

204-
/** Packet filters */
205-
Packet_filter upstream_filter_;
206-
Packet_filter downstream_filter_;
207-
208195
/** All dropped packets go here */
209196
drop_handler drop_handler_;
210197

api/net/ip4/packet_ip4.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ namespace net {
8686

8787
/** Get the IP header checksum field as-is */
8888
uint16_t ip_checksum() const noexcept
89-
{ return ntohs(ip_header().check); }
89+
{ return ip_header().check; }
9090

9191
/** Get source address */
9292
const ip4::Addr& ip_src() const noexcept
@@ -171,7 +171,7 @@ namespace net {
171171

172172
/** Set IP header checksum field directly */
173173
void set_ip_checksum(uint16_t sum) noexcept
174-
{ ip_header().check = ntohs(sum); }
174+
{ ip_header().check = sum; }
175175

176176
/** Calculate and set IP header checksum field */
177177
void set_ip_checksum() noexcept {

0 commit comments

Comments
 (0)