qubes-mirage-firewall/uplink.ml

73 lines
2.3 KiB
OCaml
Raw Normal View History

2015-12-30 08:59:13 -05:00
(* Copyright (C) 2015, Thomas Leonard <thomas.leonard@unikernel.com>
See the README file for details. *)
open Lwt.Infix
2017-03-02 09:52:55 -05:00
open Fw_utils
2015-12-30 08:59:13 -05:00
module Eth = Ethif.Make(Netif)
let src = Logs.Src.create "uplink" ~doc:"Network connection to NetVM"
module Log = (val Logs.src_log src : Logs.LOG)
2017-03-02 09:52:55 -05:00
module Make(Clock : Mirage_clock_lwt.MCLOCK) = struct
2015-12-30 08:59:13 -05:00
module Arp = Arpv4.Make(Eth)(Clock)(OS.Time)
type t = {
net : Netif.t;
eth : Eth.t;
arp : Arp.t;
interface : interface;
}
class netvm_iface eth mac ~my_ip ~other_ip : interface = object
val queue = FrameQ.create (Ipaddr.V4.to_string other_ip)
2015-12-30 08:59:13 -05:00
method my_mac = Eth.mac eth
method my_ip = my_ip
method other_ip = other_ip
2017-03-02 09:52:55 -05:00
method writev ethertype payload =
FrameQ.send queue (fun () ->
mac >>= fun dst ->
2017-03-02 09:52:55 -05:00
let eth_hdr = eth_header ethertype ~src:(Eth.mac eth) ~dst in
Eth.writev eth (eth_hdr :: payload) >|= or_raise "Write to uplink" Eth.pp_error
)
2015-12-30 08:59:13 -05:00
end
let listen t router =
Netif.listen t.net (fun frame ->
2017-03-05 11:31:04 -05:00
(* Handle one Ethernet frame from NetVM *)
Eth.input t.eth
~arpv4:(Arp.input t.arp)
~ipv4:(fun ip ->
match Nat_packet.of_ipv4_packet ip with
2017-03-06 09:30:41 -05:00
| exception ex ->
Log.err (fun f -> f "Error unmarshalling ethernet frame from uplink: %s@.%a" (Printexc.to_string ex)
Cstruct.hexdump_pp frame
);
Lwt.return_unit
2017-03-05 11:31:04 -05:00
| Error e ->
Log.warn (fun f -> f "Ignored unknown IPv4 message from uplink: %a" Nat_packet.pp_error e);
Lwt.return ()
| Ok packet ->
Firewall.ipv4_from_netvm router packet
)
~ipv6:(fun _ip -> return ())
frame
) >|= or_raise "Uplink listen loop" Netif.pp_error
2015-12-30 08:59:13 -05:00
let interface t = t.interface
2017-03-02 09:52:55 -05:00
let connect ~clock config =
2015-12-30 08:59:13 -05:00
let ip = config.Dao.uplink_our_ip in
2017-03-02 09:52:55 -05:00
Netif.connect "0" >>= fun net ->
Eth.connect net >>= fun eth ->
Arp.connect eth clock >>= fun arp ->
2015-12-30 08:59:13 -05:00
Arp.add_ip arp ip >>= fun () ->
2017-03-02 09:52:55 -05:00
let netvm_mac =
Arp.query arp config.Dao.uplink_netvm_ip
>|= or_raise "Getting MAC of our NetVM" Arp.pp_error in
let interface = new netvm_iface eth netvm_mac
~my_ip:ip
~other_ip:config.Dao.uplink_netvm_ip in
return { net; eth; arp; interface }
2015-12-30 08:59:13 -05:00
end