mirror of
https://github.com/mmueller41/genode.git
synced 2026-01-21 12:32:56 +01:00
Simple example for using CiAO/IP as userspace IP stack.
This commit is contained in:
124
repos/mml/run/raw_nic.run
Normal file
124
repos/mml/run/raw_nic.run
Normal file
@@ -0,0 +1,124 @@
|
||||
create_boot_directory
|
||||
import_from_depot [depot_user]/src/[base_src] \
|
||||
[depot_user]/pkg/[drivers_nic_pkg] \
|
||||
[depot_user]/src/init \
|
||||
[depot_user]/src/libc \
|
||||
[depot_user]/src/stdcxx \
|
||||
[depot_user]/src/nic_router \
|
||||
[depot_user]/src/vfs_audit \
|
||||
[depot_user]/src/vfs
|
||||
|
||||
append config {
|
||||
<config verbose="yes">
|
||||
|
||||
<parent-provides>
|
||||
<service name="ROM"/>
|
||||
<service name="IRQ"/>
|
||||
<service name="IO_MEM"/>
|
||||
<service name="IO_PORT"/>
|
||||
<service name="PD"/>
|
||||
<service name="RM"/>
|
||||
<service name="CPU"/>
|
||||
<service name="LOG"/>
|
||||
<service name="TOPO"/>
|
||||
</parent-provides>
|
||||
|
||||
<default-route>
|
||||
<any-service> <parent/> <any-child/> </any-service>
|
||||
</default-route>
|
||||
|
||||
<affinity-space width="64" height="1"/>
|
||||
<default caps="8192"/>
|
||||
|
||||
<start name="timer">
|
||||
<resource name="RAM" quantum="16M"/>
|
||||
<provides> <service name="Timer"/> </provides>
|
||||
</start>
|
||||
|
||||
<start name="drivers" caps="1000" managing_system="yes">
|
||||
<resource name="RAM" quantum="512M"/>
|
||||
<binary name="init"/>
|
||||
<route>
|
||||
<service name="ROM" label="config"> <parent label="drivers.config"/> </service>
|
||||
<service name="Timer"> <child name="timer"/> </service>
|
||||
<service name="Uplink"> <child name="nic_router"/> </service>
|
||||
<any-service> <parent/> </any-service>
|
||||
</route>
|
||||
</start>
|
||||
|
||||
<start name="nic_router" caps="200">
|
||||
<resource name="RAM" quantum="20M"/>
|
||||
<provides>
|
||||
<service name="Nic"/>
|
||||
<service name="Uplink"/>
|
||||
</provides>
|
||||
<config verbose_domain_state="true">
|
||||
|
||||
<policy label_prefix="rawnic" domain="downlink"/>
|
||||
<policy label_prefix="ping_1" domain="downlink"/>
|
||||
<policy label_prefix="drivers" domain="uplink"/>
|
||||
|
||||
<domain name="uplink" interface="192.168.0.2/24" gateway="192.168.0.2" verbose_packets="true">
|
||||
|
||||
<nat domain="downlink"
|
||||
tcp-ports="16384"
|
||||
udp-ports="16384"
|
||||
icmp-ids="16384"/>
|
||||
|
||||
<tcp-forward port="80" domain="downlink" to="10.0.3.55"/>
|
||||
<tcp-forward port="8080" domain="downlink" to="10.0.3.55"/>
|
||||
|
||||
<udp-forward port="7" domain="downlink" to="10.0.3.55"/>
|
||||
<udp-forward port="7070" domain="downlink" to="10.0.3.55"/>
|
||||
|
||||
</domain>
|
||||
|
||||
<domain name="downlink" interface="10.0.3.1/24" verbose_packets="true">
|
||||
|
||||
<dhcp-server ip_first="10.0.3.55" ip_last="10.0.3.55">
|
||||
<dns-server ip="8.8.8.8"/>
|
||||
<dns-server ip="1.1.1.1"/>
|
||||
</dhcp-server>
|
||||
|
||||
<tcp dst="0.0.0.0/0"><permit-any domain="uplink" /></tcp>
|
||||
<udp dst="0.0.0.0/0"><permit-any domain="uplink" /></udp>
|
||||
<icmp dst="0.0.0.0/0" domain="uplink"/>
|
||||
|
||||
</domain>
|
||||
|
||||
</config>
|
||||
</start>
|
||||
<!--
|
||||
<start name="ping_1">
|
||||
<binary name="ping"/>
|
||||
<resource name="RAM" quantum="64M"/>
|
||||
<config dst_ip="10.0.2.1"
|
||||
period_sec="1"
|
||||
verbose="no"
|
||||
count="100"
|
||||
protocol="icmp"/>
|
||||
<route>
|
||||
<service name="Nic"> <child name="nic_router"/> </service>
|
||||
<any-service> <parent/> <any-child/> </any-service>
|
||||
</route>
|
||||
</start>
|
||||
-->
|
||||
<start name="rawnic" caps="200">
|
||||
<binary name="raw_nic"/>
|
||||
<resource name="RAM" quantum="128M"/>
|
||||
<route>
|
||||
<service name="Nic"> <child name="nic_router"/> </service>
|
||||
<any-service> <parent/> <any-child/> </any-service>
|
||||
</route>
|
||||
</start>
|
||||
</config>
|
||||
}
|
||||
|
||||
append qemu_args " -nographic "
|
||||
append_qemu_nic_args "host=10.0.2.1,dhcpstart=10.0.2.55,hostfwd=tcp::10080-:80,hostfwd=tcp::18080-:8080,hostfwd=udp::10007-:7,hostfwd=udp::17070-:7070"
|
||||
|
||||
build { app/raw_nic app/ping }
|
||||
|
||||
install_config $config
|
||||
build_boot_image { raw_nic ping }
|
||||
run_genode_until forever
|
||||
128
repos/mml/src/app/raw_nic/main.cpp
Normal file
128
repos/mml/src/app/raw_nic/main.cpp
Normal file
@@ -0,0 +1,128 @@
|
||||
#include <nic_session/connection.h>
|
||||
#include <nic/packet_allocator.h>
|
||||
#include <libc/component.h>
|
||||
#include <base/heap.h>
|
||||
#include <base/mutex.h>
|
||||
|
||||
/* CiAO/IP includes */
|
||||
#include <ciao-ip/hw/hal/NetworkDevice.h>
|
||||
#include <ciao-ip/ipstack/api/Setup.h>
|
||||
#include <ciao-ip/ipstack/router/Router.h>
|
||||
#include <ciao-ip/ipstack/ipv4/IPv4.h>
|
||||
|
||||
class Raw_nic : public hw::hal::NetworkDevice
|
||||
{
|
||||
private:
|
||||
Nic::Packet_allocator _nic_tx_alloc;
|
||||
Nic::Connection _nic;
|
||||
Genode::Mutex _mutex{};
|
||||
|
||||
unsigned char _mac[6];
|
||||
|
||||
Genode::Io_signal_handler<Raw_nic> _link_state_handler;
|
||||
Genode::Io_signal_handler<Raw_nic> _rx_packet_handler;
|
||||
Genode::Io_signal_handler<Raw_nic> _tx_ready_handler;
|
||||
|
||||
enum
|
||||
{
|
||||
PACKET_SIZE = Nic::Packet_allocator::DEFAULT_PACKET_SIZE,
|
||||
BUFF_SIZE = Nic::Session::QUEUE_SIZE * PACKET_SIZE
|
||||
};
|
||||
|
||||
public:
|
||||
void handle_link_state()
|
||||
{
|
||||
Genode::log("Link state requested.");
|
||||
}
|
||||
|
||||
void handle_rx_packets()
|
||||
{
|
||||
auto &rx = *_nic.rx();
|
||||
|
||||
while (rx.packet_avail() && rx.ready_to_ack() ) {
|
||||
Nic::Packet_descriptor packet = rx.get_packet();
|
||||
Genode::log("Received packet of size ", packet.size());
|
||||
|
||||
void *eth_frame = rx.packet_content(packet);
|
||||
|
||||
demux(eth_frame, packet.size());
|
||||
if (!rx.ready_to_ack())
|
||||
return;
|
||||
|
||||
rx.acknowledge_packet(packet);
|
||||
}
|
||||
}
|
||||
|
||||
void handle_tx_ready()
|
||||
{
|
||||
auto &tx = *_nic.tx();
|
||||
|
||||
while (tx.ack_avail())
|
||||
tx.release_packet(tx.get_acked_packet());
|
||||
|
||||
Genode::log("Send packets");
|
||||
}
|
||||
|
||||
void send(const void* pkt, unsigned pkt_size ) override
|
||||
{
|
||||
try {
|
||||
Nic::Packet_descriptor pkt_desc = _nic.tx()->alloc_packet(pkt_size);
|
||||
void *pkt_base = _nic.tx()->packet_content(pkt_desc);
|
||||
|
||||
Genode::memcpy(pkt_base, pkt, pkt_size);
|
||||
|
||||
_nic.tx()->submit_packet(pkt_desc);
|
||||
} catch (Nic::Packet_stream_source<Nic::Session::Policy>::Packet_alloc_failed) {
|
||||
Genode::warning("Packet allocation has failed.");
|
||||
}
|
||||
}
|
||||
|
||||
Raw_nic(Genode::Env &env, Genode::Allocator &alloc) : _nic_tx_alloc(&alloc), _nic(env, &_nic_tx_alloc, BUFF_SIZE, BUFF_SIZE), _link_state_handler(env.ep(), *this, &Raw_nic::handle_link_state), _rx_packet_handler(env.ep(), *this, &Raw_nic::handle_rx_packets), _tx_ready_handler(env.ep(), *this, &Raw_nic::handle_tx_ready) {
|
||||
Genode::log("Created NIC session.");
|
||||
Genode::log("Registering callbacks");
|
||||
_nic.link_state_sigh(_link_state_handler);
|
||||
_nic.rx_channel()->sigh_packet_avail(_rx_packet_handler);
|
||||
_nic.rx_channel()->sigh_ready_to_ack(_rx_packet_handler);
|
||||
_nic.tx_channel()->sigh_ready_to_submit(_tx_ready_handler);
|
||||
_nic.tx_channel()->sigh_ack_avail (_tx_ready_handler);
|
||||
Genode::log("Callbacks registered. Waiting for incoming packets...");
|
||||
Genode::log("MAC address from NIC session: ", _nic.mac_address());
|
||||
_nic.mac_address().copy(_mac);
|
||||
Genode::log("Mac address read: ", _mac[0], ":", _mac[1], ":", _mac[2], ":", _mac[3], ":", _mac[4], ":", _mac[5]);
|
||||
init();
|
||||
Genode::log("Initialized CiAO/IP");
|
||||
|
||||
ipstack::Interface *interface = IP::getInterface(0);
|
||||
if (interface) {
|
||||
interface->setIPv4Addr(10, 0, 3,55);
|
||||
interface->setIPv4Subnetmask(255, 255, 255, 0);
|
||||
interface->setIPv4Up(true);
|
||||
ipstack::Router::Inst().ipv4_set_gateway_addr(ipstack::IPv4_Packet::convert_ipv4_addr(10, 0, 3, 1));
|
||||
}
|
||||
}
|
||||
|
||||
/* CiAO/IP NetworkDevice public interface */
|
||||
const char* getName() override {
|
||||
return "eth0";
|
||||
}
|
||||
|
||||
unsigned getMTU() override {
|
||||
return 1500;
|
||||
}
|
||||
|
||||
const unsigned char *getAddress() override {
|
||||
return _mac;
|
||||
}
|
||||
|
||||
unsigned char getType() override { return 1; }
|
||||
|
||||
|
||||
};
|
||||
|
||||
void Libc::Component::construct(Libc::Env &env)
|
||||
{
|
||||
static Genode::Heap heap{env.ram(), env.rm()};
|
||||
|
||||
static Raw_nic _raw_nic(env, heap);
|
||||
|
||||
}
|
||||
3
repos/mml/src/app/raw_nic/target.mk
Normal file
3
repos/mml/src/app/raw_nic/target.mk
Normal file
@@ -0,0 +1,3 @@
|
||||
TARGET = raw_nic
|
||||
SRC_CC += main.cpp
|
||||
LIBS = base libm libc stdcxx lwip
|
||||
Reference in New Issue
Block a user