aboutsummaryrefslogtreecommitdiff
path: root/bbot/machine.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'bbot/machine.cxx')
-rw-r--r--bbot/machine.cxx77
1 files changed, 58 insertions, 19 deletions
diff --git a/bbot/machine.cxx b/bbot/machine.cxx
index e8f40b3..6677de5 100644
--- a/bbot/machine.cxx
+++ b/bbot/machine.cxx
@@ -4,12 +4,11 @@
#include <bbot/machine>
+#include <unistd.h> // sleep()
+
#include <sys/un.h> // sockaddr_un
#include <sys/socket.h>
-#include <unistd.h> // getuid()
-#include <sys/types.h> // getuid()
-
#include <cstdio> // snprintf()
#include <cstring> // strcpy()
@@ -21,32 +20,58 @@ using namespace butl;
namespace bbot
{
+ // Forward TFTP requests (UDP/69) coming from the machine to the specified
+ // port.
+ //
+ // This allows the machine to connect to any "unknown" IP (e.g., link-local
+ // 196.254.111.222) port 69 and end up being redirected to out TFTP server.
+ //
+ static void
+ iptables (tracer& t,
+ const char* a,
+ const string& tap,
+ const string& br,
+ uint16_t port)
+ {
+ run (t,
+ "sudo", "iptables",
+ "-t", "nat",
+ a, "PREROUTING",
+ "-p", "udp",
+ "-m", "udp",
+ "-m", "physdev",
+ "-i", br,
+ "--physdev-in", tap,
+ "--dport", 69,
+ "-j", "DNAT",
+ "--to-destination", iface_addr (br) + ':' + to_string (port));
+ }
+
static string
- create_tap ()
+ create_tap (const string& br, uint16_t port)
{
tracer trace ("create_tap");
- string b ("br1"); // Use private bridge for now.
string t ("tap" + tc_num);
- auto uid (getuid ());
-
// First try to delete it in case there is one from a previous run.
//
run_exit (trace, "sudo", "ip", "tuntap", "delete", t, "mode", "tap");
run (trace, "sudo", "ip", "tuntap", "add", t, "mode", "tap", "user", uid);
run (trace, "sudo", "ip", "link", "set", t, "up");
- //sleep (1);
- run (trace, "sudo", "ip", "link", "set", t, "master", b);
+ run (trace, "sudo", "ip", "link", "set", t, "master", br);
+
+ iptables (trace, "-A", t, br, port); // Add.
return t;
}
static void
- destroy_tap (const string& t)
+ destroy_tap (const string& t, const string& br, uint16_t port)
{
- tracer trace ("create_tap");
+ tracer trace ("destroy_tap");
+ iptables (trace, "-D", t, br, port); // Delete.
run (trace, "sudo", "ip", "tuntap", "delete", t, "mode", "tap");
}
@@ -74,7 +99,9 @@ namespace bbot
public:
kvm_machine (const dir_path&,
const machine_manifest&,
- const optional<string>& mac);
+ const optional<string>& mac,
+ const string& br_iface,
+ uint16_t tftp_port);
virtual bool
shutdown () override;
@@ -91,7 +118,11 @@ namespace bbot
private:
path kvm; // Hypervisor binary.
- string tap; // Tap network interface.
+
+ string br; // Bridge network interface.
+ string tap; // Tap network interface.
+ uint16_t port; // TFTP port.
+
path monitor; // QEMU monitor UNIX socket.
process proc;
};
@@ -99,12 +130,16 @@ namespace bbot
kvm_machine::
kvm_machine (const dir_path& md,
const machine_manifest& mm,
- const optional<string>& omac)
+ const optional<string>& omac,
+ const string& br,
+ uint16_t port)
: machine (mm.mac ? *mm.mac : // Fixed mac from machine manifest.
omac ? *omac : // Generated mac from previous bootstrap.
generate_mac ()),
kvm ("kvm"),
- tap (create_tap ()),
+ br (br),
+ tap (create_tap (br, port)),
+ port (port),
monitor ("/tmp/" + tc_name + "-monitor")
{
tracer trace ("kvm_machine");
@@ -203,7 +238,7 @@ namespace bbot
{
run_io_finish (trace, proc, kvm);
- destroy_tap (tap);
+ destroy_tap (tap, br, port);
try_rmfile (monitor, true); // QEMU doesn't seem to remove it.
}
@@ -281,12 +316,16 @@ namespace bbot
unique_ptr<machine>
start_machine (const dir_path& md,
const machine_manifest& mm,
- const optional<string>& mac)
+ const optional<string>& mac,
+ const string& br_iface,
+ uint16_t tftp_port)
{
switch (mm.type)
{
- case machine_type::kvm: return make_unique<kvm_machine> (md, mm, mac);
- case machine_type::nspawn: assert (false); //@@ TODO
+ case machine_type::kvm:
+ return make_unique<kvm_machine> (md, mm, mac, br_iface, tftp_port);
+ case machine_type::nspawn:
+ assert (false); //@@ TODO
}
return nullptr;