Skip to content

Commit b7cf8a3

Browse files
Merge branch 'dev' of github.com:alfred-bratterud/IncludeOS into dev
2 parents dc319ab + 77da39e commit b7cf8a3

4 files changed

Lines changed: 134 additions & 55 deletions

File tree

api/net/inet.hpp

Lines changed: 54 additions & 2 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,6 +48,7 @@ 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
///
@@ -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
///
@@ -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: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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/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

src/net/ip4/ip4.cpp

Lines changed: 47 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,7 @@ namespace net {
3434
packets_rx_ {Statman::get().create(Stat::UINT64, inet.ifname() + ".ip4.packets_rx").get_uint64()},
3535
packets_tx_ {Statman::get().create(Stat::UINT64, inet.ifname() + ".ip4.packets_tx").get_uint64()},
3636
packets_dropped_ {Statman::get().create(Stat::UINT32, inet.ifname() + ".ip4.packets_dropped").get_uint32()},
37-
stack_ {inet},
38-
upstream_filter_ {this, &IP4::filter_upstream},
39-
downstream_filter_{this, &IP4::filter_downstream}
37+
stack_ {inet}
4038
{}
4139

4240

@@ -50,7 +48,7 @@ namespace net {
5048
}
5149

5250

53-
IP4::IP_packet_ptr IP4::filter_upstream(IP4::IP_packet_ptr packet)
51+
IP4::IP_packet_ptr IP4::drop_invalid_in(IP4::IP_packet_ptr packet)
5452
{
5553
IP4::Direction up = IP4::Direction::Upstream;
5654

@@ -73,7 +71,7 @@ namespace net {
7371
}
7472

7573

76-
IP4::IP_packet_ptr IP4::filter_downstream(IP4::IP_packet_ptr packet)
74+
IP4::IP_packet_ptr IP4::drop_invalid_out(IP4::IP_packet_ptr packet)
7775
{
7876
// RFC-1122 3.2.1.7, MUST NOT send packet with TTL of 0
7977
if (packet->ip_ttl() == 0)
@@ -102,7 +100,12 @@ namespace net {
102100
// Stat increment packets received
103101
packets_rx_++;
104102

105-
packet = upstream_filter_(std::move(packet));
103+
104+
packet = drop_invalid_in(std::move(packet));
105+
if (UNLIKELY(packet == nullptr)) return;
106+
107+
// Enter prerouting chain
108+
packet = stack_.prerouting_chain()(std::move(packet), stack_);
106109
if (UNLIKELY(packet == nullptr)) return;
107110

108111
// Drop / forward if my ip address doesn't match dest. or broadcast
@@ -122,6 +125,9 @@ namespace net {
122125
return;
123126
}
124127

128+
packet = stack_.input_chain()(std::move(packet), stack_);
129+
if (UNLIKELY(packet == nullptr)) return;
130+
125131
// Pass packet to it's respective protocol controller
126132
switch (packet->ip_protocol()) {
127133
case Protocol::ICMPv4:
@@ -152,56 +158,62 @@ namespace net {
152158
void IP4::transmit(Packet_ptr pckt) {
153159
assert((size_t)pckt->size() > sizeof(header));
154160

155-
auto ip4_pckt = static_unique_ptr_cast<PacketIP4>(std::move(pckt));
161+
auto packet = static_unique_ptr_cast<PacketIP4>(std::move(pckt));
162+
163+
packet->make_flight_ready();
156164

157-
ip4_pckt->make_flight_ready();
165+
packet = stack_.output_chain()(std::move(packet), stack_);
166+
if (UNLIKELY(packet == nullptr)) return;
158167

159-
ship(std::move(ip4_pckt));
168+
ship(std::move(packet));
160169
}
161170

162-
void IP4::ship(Packet_ptr pckt)
171+
void IP4::ship(Packet_ptr pckt, addr next_hop)
163172
{
164-
auto ip4_pckt = static_unique_ptr_cast<PacketIP4>(std::move(pckt));
173+
auto packet = static_unique_ptr_cast<PacketIP4>(std::move(pckt));
165174

166175
// Send loopback packets right back
167-
if (UNLIKELY(stack_.is_loopback(ip4_pckt->ip_dst()))) {
176+
if (UNLIKELY(stack_.is_loopback(packet->ip_dst()))) {
168177
debug("<IP4> Destination address is loopback \n");
169-
IP4::receive(std::move(ip4_pckt));
178+
IP4::receive(std::move(packet));
170179
return;
171180
}
172181

173-
addr next_hop;
182+
// Filter illegal egress packets
183+
packet = drop_invalid_out(std::move(packet));
184+
if (packet == nullptr) return;
174185

175-
if (ip4_pckt->ip_dst() != IP4::ADDR_BCAST)
176-
{
177-
// Create local and target subnets
178-
addr target = ip4_pckt->ip_dst() & stack_.netmask();
179-
addr local = stack_.ip_addr() & stack_.netmask();
186+
packet = stack_.postrouting_chain()(std::move(packet), stack_);
187+
if (UNLIKELY(packet == nullptr)) return;
180188

181-
// Compare subnets to know where to send packet
182-
next_hop = target == local ? ip4_pckt->ip_dst() : stack_.gateway();
183189

184-
debug("<IP4 TOP> Next hop for %s, (netmask %s, local IP: %s, gateway: %s) == %s\n",
185-
ip4_pckt->ip_dst().str().c_str(),
186-
stack_.netmask().str().c_str(),
187-
stack_.ip_addr().str().c_str(),
188-
stack_.gateway().str().c_str(),
189-
next_hop.str().c_str());
190+
if (next_hop == 0) {
191+
if (UNLIKELY(packet->ip_dst() == IP4::ADDR_BCAST)) {
192+
next_hop = IP4::ADDR_BCAST;
193+
} else {
194+
// Create local and target subnets
195+
addr target = packet->ip_dst() & stack_.netmask();
196+
addr local = stack_.ip_addr() & stack_.netmask();
190197

191-
} else {
192-
next_hop = IP4::ADDR_BCAST;
193-
}
198+
// Compare subnets to know where to send packet
199+
next_hop = target == local ? packet->ip_dst() : stack_.gateway();
194200

195-
// Filter illegal egress packets
196-
ip4_pckt = upstream_filter_(std::move(ip4_pckt));
197-
if (ip4_pckt == nullptr) return;
201+
debug("<IP4 TOP> Next hop for %s, (netmask %s, local IP: %s, gateway: %s) == %s\n",
202+
packet->ip_dst().str().c_str(),
203+
stack_.netmask().str().c_str(),
204+
stack_.ip_addr().str().c_str(),
205+
stack_.gateway().str().c_str(),
206+
next_hop.str().c_str());
207+
208+
}
209+
}
198210

199211
// Stat increment packets transmitted
200212
packets_tx_++;
201213

202-
debug("<IP4> Transmitting packet, layer begin: buf + %li\n", ip4_pckt->layer_begin() - ip4_pckt->buf());
214+
debug("<IP4> Transmitting packet, layer begin: buf + %li\n", packet->layer_begin() - packet->buf());
203215

204-
linklayer_out_(std::move(ip4_pckt), next_hop);
216+
linklayer_out_(std::move(packet), next_hop);
205217
}
206218

207219
} //< namespace net

0 commit comments

Comments
 (0)