diff options
Diffstat (limited to 'bbot/machine.cxx')
-rw-r--r-- | bbot/machine.cxx | 77 |
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; |