Skip to content

Commit 95c6d0d

Browse files
authored
Merge pull request #1199 from alfred-bratterud/dev
IP-stack horror: proper isolation between layers
2 parents 72eb571 + b0e01b7 commit 95c6d0d

47 files changed

Lines changed: 1156 additions & 879 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ init_submodule(mod/uzlib)
5757
set(OPTIMIZE "-O2")
5858

5959
if(debug OR debug-info OR debug-all)
60-
set(CAPABS "${CAPABS} -O0")
60+
set(OTPIMIZE "-O0")
6161
endif(debug OR debug-info OR debug-all)
6262

6363
if(minimal)

api/hw/mac_addr.hpp

Lines changed: 84 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -25,69 +25,90 @@
2525
#include <string>
2626
#include <cstring> // strncmp
2727

28-
namespace hw {
29-
// MAC address
30-
union MAC_addr {
31-
// no. parts in a MAC address
32-
static constexpr size_t PARTS_LEN = 6;
33-
// The parts of the MAC address
34-
uint8_t part[PARTS_LEN];
35-
36-
struct {
37-
uint16_t minor;
38-
uint32_t major;
39-
} __attribute__((packed));
40-
41-
MAC_addr() noexcept : part{} {}
42-
43-
MAC_addr(const uint8_t a, const uint8_t b, const uint8_t c,
44-
const uint8_t d, const uint8_t e, const uint8_t f) noexcept
45-
: part{a,b,c,d,e,f}
46-
{}
47-
48-
MAC_addr& operator=(const MAC_addr cpy) noexcept {
49-
minor = cpy.minor;
50-
major = cpy.major;
51-
return *this;
52-
}
53-
54-
/**
55-
* @brief Hex representation of a MAC address
56-
*
57-
* @return hex string representation
58-
*/
59-
std::string hex_str() const {
60-
char hex_addr[18];
61-
snprintf(hex_addr, sizeof(hex_addr), "%02x:%02x:%02x:%02x:%02x:%02x",
62-
part[0], part[1], part[2],
63-
part[3], part[4], part[5]);
64-
return hex_addr;
65-
}
66-
67-
/**
68-
* @brief String representation of a MAC address
69-
* @note default is hex
70-
* @return string representation of the MAC address
71-
*/
72-
std::string str() const
73-
{ return hex_str(); }
74-
75-
std::string to_string() const
76-
{ return str(); }
77-
78-
operator std::string () const
79-
{ return str(); }
80-
81-
/** Check for equality */
82-
bool operator==(const MAC_addr mac) const noexcept
83-
{
84-
return strncmp(
85-
reinterpret_cast<const char*>(part),
86-
reinterpret_cast<const char*>(mac.part),
87-
PARTS_LEN) == 0;
88-
}
89-
90-
} __attribute__((packed)); //< union addr
28+
namespace MAC {
29+
30+
// MAC address
31+
union Addr {
32+
// no. parts in a MAC address
33+
static constexpr size_t PARTS_LEN = 6;
34+
// The parts of the MAC address
35+
uint8_t part[PARTS_LEN];
36+
37+
struct {
38+
uint16_t minor;
39+
uint32_t major;
40+
} __attribute__((packed));
41+
42+
Addr() noexcept : part{} {}
43+
44+
Addr(const uint8_t a, const uint8_t b, const uint8_t c,
45+
const uint8_t d, const uint8_t e, const uint8_t f) noexcept
46+
: part{a,b,c,d,e,f}
47+
{}
48+
49+
Addr& operator=(const Addr cpy) noexcept {
50+
minor = cpy.minor;
51+
major = cpy.major;
52+
return *this;
53+
}
54+
55+
56+
/**
57+
* @brief Hex representation of a MAC address
58+
*
59+
* @return hex string representation
60+
*/
61+
std::string hex_str() const {
62+
char hex_addr[18];
63+
snprintf(hex_addr, sizeof(hex_addr), "%02x:%02x:%02x:%02x:%02x:%02x",
64+
part[0], part[1], part[2],
65+
part[3], part[4], part[5]);
66+
return hex_addr;
67+
}
68+
69+
/**
70+
* @brief String representation of a MAC address
71+
* @note default is hex
72+
* @return string representation of the MAC address
73+
*/
74+
std::string str() const
75+
{ return hex_str(); }
76+
77+
std::string to_string() const
78+
{ return str(); }
79+
80+
operator std::string () const
81+
{ return str(); }
82+
83+
/** Check for equality */
84+
bool operator==(const Addr mac) const noexcept
85+
{
86+
return strncmp(
87+
reinterpret_cast<const char*>(part),
88+
reinterpret_cast<const char*>(mac.part),
89+
PARTS_LEN) == 0;
90+
}
91+
92+
bool operator!=(const Addr mac) const noexcept
93+
{ return not(*this == mac); }
94+
95+
} __attribute__((packed)); //< union addr
96+
97+
const Addr EMPTY {0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
98+
99+
// uint16_t(0xFFFF), uint32_t(0xFFFFFFFF)
100+
const Addr BROADCAST {0xff,0xff,0xff,0xff,0xff,0xff};
101+
102+
// uint16_t(0x0000), uint32_t(0x01000000)
103+
const Addr MULTICAST {0,0,0x01,0,0,0};
104+
105+
// uint16_t(0x3333), uint32_t(0x01000000)
106+
const Addr IPv6mcast_01 {0x33,0x33,0x01,0,0,0};
107+
108+
// uint16_t(0x3333), uint32_t(0x02000000)
109+
const Addr IPv6mcast_02 {0x33,0x33,0x02,0,0,0};
110+
111+
91112
}
92113

93114
#endif

api/hw/nic.hpp

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020

2121
#include "../net/buffer_store.hpp"
2222
#include "mac_addr.hpp"
23-
#include <net/frame.hpp>
2423
#include <net/inet_common.hpp>
2524

2625
namespace hw {
@@ -31,7 +30,7 @@ namespace hw {
3130
class Nic {
3231
public:
3332
using upstream = delegate<void(net::Packet_ptr)>;
34-
using downstream = upstream;
33+
using downstream = net::downstream_link;
3534

3635
enum class Proto {ETH, IEEE802111};
3736

@@ -49,7 +48,7 @@ namespace hw {
4948
{ return "NIC"; }
5049

5150
/** The mac address. */
52-
virtual const MAC_addr& mac() const noexcept = 0;
51+
virtual const MAC::Addr& mac() const noexcept = 0;
5352

5453
virtual uint16_t MTU() const noexcept = 0;
5554

@@ -65,7 +64,17 @@ namespace hw {
6564
size_t buffers_available()
6665
{ return bufstore_.available(); }
6766

68-
virtual net::Packet_ptr create_packet(uint16_t) = 0;
67+
/** Number of bytes in a frame needed by the device itself **/
68+
virtual size_t frame_offset_device() = 0;
69+
70+
/** Number of bytes in a frame needed by the link layer **/
71+
virtual size_t frame_offset_link() = 0;
72+
73+
/**
74+
* Create a packet with appropriate size for the underlying link
75+
* @param layer_begin : offset in octets from the link-layer header
76+
*/
77+
virtual net::Packet_ptr create_packet(int layer_begin) = 0;
6978

7079
/** Subscribe to event for when there is more room in the tx queue */
7180
void on_transmit_queue_available(net::transmit_avail_delg del)
@@ -75,6 +84,12 @@ namespace hw {
7584

7685
virtual void deactivate() = 0;
7786

87+
/** Stats getters **/
88+
virtual uint64_t get_packets_rx() = 0;
89+
virtual uint64_t get_packets_tx() = 0;
90+
virtual uint64_t get_packets_dropped() = 0;
91+
92+
/** Move this nic to current CPU **/
7893
virtual void move_to_this_cpu() = 0;
7994

8095
virtual ~Nic() {}

api/kernel/irq_manager.hpp

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -126,10 +126,16 @@ class alignas(SMP_ALIGN) IRQ_manager {
126126
/** process all pending interrupts */
127127
void process_interrupts();
128128

129+
std::array<uint64_t*,IRQ_LINES>& get_count_handled()
130+
{ return count_handled; }
131+
132+
std::array<uint64_t,IRQ_LINES>& get_count_received()
133+
{ return count_received; }
134+
129135
/** Initialize for a local APIC */
130136
static void init(int cpuid);
131-
132137
IRQ_manager() = default;
138+
133139
private:
134140
IRQ_manager(IRQ_manager&) = delete;
135141
IRQ_manager(IRQ_manager&&) = delete;
@@ -138,7 +144,8 @@ class alignas(SMP_ALIGN) IRQ_manager {
138144

139145
IDTDescr idt[INTR_LINES];
140146
irq_delegate irq_delegates_[IRQ_LINES];
141-
uint64_t* counters[IRQ_LINES];
147+
std::array<uint64_t*,IRQ_LINES> count_handled;
148+
std::array<uint64_t, IRQ_LINES> count_received;
142149

143150
MemBitmap irq_subs;
144151
MemBitmap irq_pend;

api/net/ethernet/ethernet.hpp

Lines changed: 17 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,8 @@
2020
#define NET_ETHERNET_HPP
2121

2222
#include <string>
23-
24-
#include "frame.hpp"
2523
#include "header.hpp"
24+
#include "ethertype.hpp"
2625
#include <hw/mac_addr.hpp> // ethernet address
2726
#include <hw/nic.hpp> // protocol
2827
#include <net/inet_common.hpp>
@@ -34,41 +33,8 @@ namespace net {
3433
public:
3534
static constexpr size_t MINIMUM_PAYLOAD = 46;
3635

37-
/**
38-
* Some big-endian ethernet types
39-
*
40-
* From http://en.wikipedia.org/wiki/EtherType
41-
*/
42-
enum ethertype_le {
43-
_ETH_IP4 = 0x0800,
44-
_ETH_ARP = 0x0806,
45-
_ETH_WOL = 0x0842,
46-
_ETH_IP6 = 0x86DD,
47-
_ETH_FLOW = 0x8808,
48-
_ETH_JUMBO = 0x8870
49-
};
50-
51-
/** Little-endian ethertypes. */
52-
enum ethertype {
53-
ETH_IP4 = 0x8,
54-
ETH_ARP = 0x608,
55-
ETH_WOL = 0x4208,
56-
ETH_IP6 = 0xdd86,
57-
ETH_FLOW = 0x888,
58-
ETH_JUMBO = 0x7088,
59-
ETH_VLAN = 0x81
60-
};
61-
62-
using Frame = ethernet::Frame;
63-
6436
// MAC address
65-
using addr = hw::MAC_addr;
66-
67-
static const addr MULTICAST_FRAME;
68-
static const addr BROADCAST_FRAME;
69-
70-
static const addr IPv6mcast_01;
71-
static const addr IPv6mcast_02;
37+
using addr = MAC::Addr;
7238

7339
/** Constructor */
7440
explicit Ethernet(downstream physical_downstream, const addr& mac) noexcept;
@@ -106,13 +72,23 @@ namespace net {
10672
{ return physical_downstream_; }
10773

10874
static constexpr uint16_t header_size() noexcept
109-
{ return sizeof(ethernet::Header) + sizeof(ethernet::trailer_t); }
75+
{ return sizeof(ethernet::Header); }
11076

11177
static constexpr hw::Nic::Proto proto() noexcept
11278
{ return hw::Nic::Proto::ETH; }
11379

11480
/** Transmit data, with preallocated space for eth.header */
115-
void transmit(Packet_ptr);
81+
void transmit(Packet_ptr, addr dest, Ethertype);
82+
83+
/** Stats getters **/
84+
uint64_t get_packets_rx()
85+
{ return packets_rx_; }
86+
87+
uint64_t get_packets_tx()
88+
{ return packets_tx_; }
89+
90+
uint64_t get_packets_dropped()
91+
{ return packets_dropped_; }
11692

11793
private:
11894
const addr& mac_;
@@ -123,9 +99,9 @@ namespace net {
12399
uint32_t& packets_dropped_;
124100

125101
/** Upstream OUTPUT connections */
126-
upstream ip4_upstream_ = [](net::Packet_ptr){};
127-
upstream ip6_upstream_ = [](net::Packet_ptr){};
128-
upstream arp_upstream_ = [](net::Packet_ptr){};
102+
upstream ip4_upstream_ = nullptr;
103+
upstream ip6_upstream_ = nullptr;
104+
upstream arp_upstream_ = nullptr;
129105

130106
/** Downstream OUTPUT connection */
131107
downstream physical_downstream_ = [](Packet_ptr){};

api/net/ethernet/ethertype.hpp

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
// This file is a part of the IncludeOS unikernel - www.includeos.org
2+
//
3+
// Copyright 2015 Oslo and Akershus University College of Applied Sciences
4+
// and Alfred Bratterud
5+
//
6+
// Licensed under the Apache License, Version 2.0 (the "License");
7+
// you may not use this file except in compliance with the License.
8+
// You may obtain a copy of the License at
9+
//
10+
// http://www.apache.org/licenses/LICENSE-2.0
11+
//
12+
// Unless required by applicable law or agreed to in writing, software
13+
// distributed under the License is distributed on an "AS IS" BASIS,
14+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
// See the License for the specific language governing permissions and
16+
// limitations under the License.
17+
18+
#pragma once
19+
#ifndef NET_ETHERTYPE_HPP
20+
#define NET_ETHERTYPE_HPP
21+
22+
23+
namespace net {
24+
25+
/** Little-endian ethertypes. More entries here:
26+
http://www.iana.org/assignments/ieee-802-numbers/ieee-802-numbers.xhtml */
27+
enum class Ethertype : uint16_t {
28+
IP4 = 0x8,
29+
ARP = 0x608,
30+
WOL = 0x4208,
31+
IP6 = 0xdd86,
32+
FLOW = 0x888,
33+
JUMBO = 0x7088,
34+
VLAN = 0x81
35+
};
36+
37+
}
38+
39+
#endif

0 commit comments

Comments
 (0)