2015-12-30 04:52:24 -05:00
|
|
|
(* Copyright (C) 2015, Thomas Leonard <thomas.leonard@unikernel.com>
|
|
|
|
See the README file for details. *)
|
|
|
|
|
|
|
|
open Utils
|
|
|
|
|
|
|
|
let src = Logs.Src.create "router" ~doc:"Router"
|
|
|
|
module Log = (val Logs.src_log src : Logs.LOG)
|
|
|
|
|
2015-12-30 11:07:16 -05:00
|
|
|
(* The routing table *)
|
|
|
|
|
2015-12-30 04:52:24 -05:00
|
|
|
type t = {
|
2015-12-30 08:48:13 -05:00
|
|
|
client_eth : Client_eth.t;
|
2016-01-02 10:50:05 -05:00
|
|
|
mutable nat : Nat_lookup.t;
|
2016-01-01 06:32:57 -05:00
|
|
|
uplink : interface;
|
2015-12-30 04:52:24 -05:00
|
|
|
}
|
|
|
|
|
2016-01-01 06:32:57 -05:00
|
|
|
let create ~client_eth ~uplink =
|
2015-12-30 11:07:16 -05:00
|
|
|
let nat = Nat_lookup.empty () in
|
2016-01-01 06:32:57 -05:00
|
|
|
{ client_eth; nat; uplink }
|
2015-12-30 04:52:24 -05:00
|
|
|
|
|
|
|
let target t buf =
|
|
|
|
let open Wire_structs.Ipv4_wire in
|
|
|
|
let dst_ip = get_ipv4_dst buf |> Ipaddr.V4.of_int32 in
|
2015-12-30 08:48:13 -05:00
|
|
|
if Ipaddr.V4.Prefix.mem dst_ip (Client_eth.prefix t.client_eth) then (
|
|
|
|
match Client_eth.lookup t.client_eth dst_ip with
|
2015-12-30 04:52:24 -05:00
|
|
|
| Some client_link -> Some (client_link :> interface)
|
|
|
|
| None ->
|
2016-01-08 06:31:27 -05:00
|
|
|
Log.warn (fun f -> f "Packet to unknown internal client %a - dropping"
|
|
|
|
Ipaddr.V4.pp_hum dst_ip);
|
2015-12-30 04:52:24 -05:00
|
|
|
None
|
2016-01-01 06:32:57 -05:00
|
|
|
) else Some t.uplink
|
2015-12-30 04:52:24 -05:00
|
|
|
|
2015-12-30 08:48:13 -05:00
|
|
|
let add_client t = Client_eth.add_client t.client_eth
|
|
|
|
let remove_client t = Client_eth.remove_client t.client_eth
|
|
|
|
|
2015-12-30 11:07:16 -05:00
|
|
|
let classify t ip =
|
2016-01-01 06:32:57 -05:00
|
|
|
if ip = Ipaddr.V4 t.uplink#my_ip then `Firewall_uplink
|
|
|
|
else if ip = Ipaddr.V4 t.uplink#other_ip then `NetVM
|
2015-12-30 11:07:16 -05:00
|
|
|
else (Client_eth.classify t.client_eth ip :> Packet.host)
|
2016-01-01 06:32:57 -05:00
|
|
|
|
|
|
|
let resolve t = function
|
|
|
|
| `Firewall_uplink -> Ipaddr.V4 t.uplink#my_ip
|
|
|
|
| `NetVM -> Ipaddr.V4 t.uplink#other_ip
|
|
|
|
| #Client_eth.host as host -> Client_eth.resolve t.client_eth host
|
2016-01-02 10:50:05 -05:00
|
|
|
|
|
|
|
let reset t =
|
|
|
|
t.nat <- Nat_lookup.empty ()
|