Skip to content

Commit 8d6abd6

Browse files
authored
Merge pull request #46 from hannesm/layering
adjust to mirage-net.2.0.0
2 parents d983ed3 + 15ca39d commit 8d6abd6

File tree

5 files changed

+50
-53
lines changed

5 files changed

+50
-53
lines changed

.travis.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ script: bash -ex ./.travis-docker.sh
77
env:
88
global:
99
- PACKAGE="mirage-net-unix"
10+
- EXTRA_REMOTES="https://github.com/mirage/mirage-dev.git#layering"
1011
matrix:
1112
- DISTRO="alpine" OCAML_VERSION="4.04"
1213
- DISTRO="alpine" OCAML_VERSION="4.05"

mirage-net-unix.opam

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,17 +13,18 @@ depends: [
1313
"cstruct" {>= "1.7.1"}
1414
"cstruct-lwt"
1515
"lwt" {>= "2.4.3"}
16-
"mirage-net-lwt" {>= "1.0.0"}
17-
"io-page-unix" {>= "2.0.0"}
18-
"tuntap" {>= "1.3.0"}
16+
"mirage-net-lwt" {>= "2.0.0"}
17+
"tuntap" {>= "1.8.0"}
1918
"alcotest" {with-test}
19+
"logs"
20+
"macaddr"
2021
]
2122
build: [
2223
["dune" "subst"] {pinned}
2324
["dune" "build" "-p" name "-j" jobs]
2425
]
2526
dev-repo: "git+https://github.com/mirage/mirage-net-unix.git"
26-
synopsis: "Unix implementation of the Mirage NETWORK interface"
27+
synopsis: "Unix implementation of the Mirage_net_lwt interface"
2728
description: """
2829
This interface exposes raw Ethernet frames using `ocaml-tuntap`,
2930
suitable for use with an OCaml network stack such as the one

src/dune

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
(library
22
(name mirage_net_unix)
33
(public_name mirage-net-unix)
4-
(libraries io-page-unix cstruct cstruct-lwt lwt.unix mirage-net-lwt tuntap)
4+
(libraries logs macaddr cstruct cstruct-lwt lwt.unix mirage-net-lwt tuntap)
55
(wrapped false))

src/netif.ml

Lines changed: 40 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -14,43 +14,40 @@
1414
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
1515
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
1616
*)
17+
open Lwt.Infix
1718

1819
[@@@warning "-52"]
19-
open Result
2020
open Mirage_net
2121

22-
let log fmt = Format.printf ("Netif: " ^^ fmt ^^ "\n%!")
23-
24-
let (>>=) = Lwt.(>>=)
25-
let (>|=) = Lwt.(>|=)
22+
let src = Logs.Src.create "netif" ~doc:"Mirage unix network module"
23+
module Log = (val Logs.src_log src : Logs.LOG)
2624

2725
type +'a io = 'a Lwt.t
2826

2927
type t = {
3028
id: string;
3129
dev: Lwt_unix.file_descr;
3230
mutable active: bool;
33-
mutable mac: Macaddr.t;
31+
mac: Macaddr.t;
32+
mtu : int;
3433
stats : Mirage_net.stats;
3534
}
3635

3736
let fd t = t.dev
3837

3938
type error = [
40-
| Mirage_net.error
39+
| Mirage_net.Net.error
4140
| `Partial of string * int * Cstruct.t
4241
| `Exn of exn
4342
]
4443

4544
let pp_error ppf = function
46-
| #Mirage_net.error as e -> Mirage_net.pp_error ppf e
45+
| #Mirage_net.Net.error as e -> Mirage_net.Net.pp_error ppf e
4746
| `Partial (id, len', buffer) ->
4847
Fmt.pf ppf "netif %s: partial write (%d, expected %d)"
4948
id len' buffer.Cstruct.len
5049
| `Exn e -> Fmt.exn ppf e
5150

52-
let devices = Hashtbl.create 1
53-
5451
let err_permission_denied devname =
5552
Printf.sprintf
5653
"Permission denied while opening the %s device. Please re-run using sudo."
@@ -63,34 +60,33 @@ let connect devname =
6360
let dev = Lwt_unix.of_unix_file_descr ~blocking:true fd in
6461
let mac = Macaddr.make_local (fun _ -> Random.int 256) in
6562
Tuntap.set_up_and_running devname;
66-
log "plugging into %s with mac %s" devname (Macaddr.to_string mac);
63+
let mtu = Tuntap.get_mtu devname in
64+
Log.debug (fun m -> m "plugging into %s with mac %a and mtu %d"
65+
devname Macaddr.pp mac mtu);
6766
let active = true in
6867
let t = {
69-
id=devname; dev; active; mac;
68+
id=devname; dev; active; mac; mtu;
7069
stats= { rx_bytes=0L;rx_pkts=0l; tx_bytes=0L; tx_pkts=0l } }
7170
in
72-
Hashtbl.add devices devname t;
73-
log "connect %s" devname;
71+
Log.info (fun m -> m "connect %s with mac %a" devname Macaddr.pp mac);
7472
Lwt.return t
7573
with
7674
| Failure "tun[open]: Permission denied" ->
7775
Lwt.fail_with (err_permission_denied devname)
7876
| exn -> Lwt.fail exn
7977

8078
let disconnect t =
81-
log "disconnect %s" t.id;
79+
Log.info (fun m -> m "disconnect %s" t.id);
8280
t.active <- false;
8381
Lwt_unix.close t.dev >>= fun () ->
8482
Tuntap.closetap t.id;
8583
Lwt.return_unit
8684

8785
type macaddr = Macaddr.t
88-
type page_aligned_buffer = Io_page.t
8986
type buffer = Cstruct.t
9087

9188
(* Input a frame, and block if nothing is available *)
92-
let rec read t page =
93-
let buf = Io_page.to_cstruct page in
89+
let rec read t buf =
9490
let process () =
9591
Lwt.catch (fun () ->
9692
Lwt_cstruct.read t.dev buf >|= function
@@ -103,17 +99,17 @@ let rec read t page =
10399
Ok buf)
104100
(function
105101
| Unix.Unix_error(Unix.ENXIO, _, _) ->
106-
log "[read] device %s is down, stopping" t.id;
102+
Log.err (fun m -> m "[read] device %s is down, stopping" t.id);
107103
Lwt.return (Error `Disconnected)
108104
| Lwt.Canceled ->
109-
log "[read] user program requested cancellation of listen on %s" t.id;
105+
Log.err (fun m -> m "[read] user program requested cancellation of listen on %s" t.id);
110106
Lwt.return (Error `Canceled)
111107
| exn ->
112-
log "[read] error: %s, continuing" (Printexc.to_string exn);
108+
Log.err (fun m -> m "[read] error: %s, continuing" (Printexc.to_string exn));
113109
Lwt.return (Error `Continue))
114110
in
115111
process () >>= function
116-
| Error `Continue -> read t page
112+
| Error `Continue -> read t buf
117113
| Error `Canceled -> Lwt.return (Error `Canceled)
118114
| Error `Disconnected -> Lwt.return (Error `Disconnected)
119115
| Ok buf -> Lwt.return (Ok buf)
@@ -122,51 +118,50 @@ let safe_apply f x =
122118
Lwt.catch
123119
(fun () -> f x)
124120
(fun exn ->
125-
log "[listen] error while handling %s, continuing. bt: %s"
126-
(Printexc.to_string exn) (Printexc.get_backtrace ());
121+
Log.err (fun m -> m "[listen] error while handling %s, continuing. bt: %s"
122+
(Printexc.to_string exn) (Printexc.get_backtrace ()));
127123
Lwt.return_unit)
128124

125+
129126
(* Loop and listen for packets permanently *)
130127
(* this function has to be tail recursive, since it is called at the
131128
top level, otherwise memory of received packets and all reachable
132129
data is never claimed. take care when modifying, here be dragons! *)
133-
let rec listen t fn =
130+
let rec listen t ~header_size fn =
134131
match t.active with
135132
| true ->
136-
let page = Io_page.get 1 in
133+
let buf = Cstruct.create (t.mtu + header_size) in
137134
let process () =
138-
read t page >|= function
135+
read t buf >|= function
139136
| Ok buf -> Lwt.async (fun () -> safe_apply fn buf) ; Ok ()
140137
| Error `Canceled -> Error `Disconnected
141138
| Error `Disconnected -> t.active <- false ; Error `Disconnected
142139
in
143140
process () >>= (function
144-
| Ok () -> (listen[@tailcall]) t fn
141+
| Ok () -> (listen[@tailcall]) t ~header_size fn
145142
| Error e -> Lwt.return (Error e))
146143
| false -> Lwt.return (Ok ())
147144

148145
(* Transmit a packet from a Cstruct.t *)
149-
let write t buffer =
150-
let open Cstruct in
151-
(* Unfortunately we peek inside the cstruct type here: *)
146+
let write t ~size fillf =
152147
(* This is the interface to the cruel Lwt world with exceptions, we've to guard *)
153-
Lwt.catch (fun () ->
154-
Lwt_bytes.write t.dev buffer.buffer buffer.off buffer.len >|= fun len' ->
155-
t.stats.tx_pkts <- Int32.succ t.stats.tx_pkts;
156-
t.stats.tx_bytes <- Int64.add t.stats.tx_bytes (Int64.of_int buffer.len);
157-
if len' <> buffer.len then Error (`Partial (t.id, len', buffer))
158-
else Ok ())
159-
(fun exn -> Lwt.return (Error (`Exn exn)))
160-
161-
162-
let writev t = function
163-
| [] -> Lwt.return (Ok ())
164-
| [page] -> write t page
165-
| pages ->
166-
write t @@ Cstruct.concat pages
148+
let buf = Cstruct.create size in
149+
let len = fillf buf in
150+
if len > size then
151+
Lwt.return (Error `Invalid_length)
152+
else
153+
Lwt.catch (fun () ->
154+
Lwt_bytes.write t.dev buf.Cstruct.buffer 0 len >|= fun len' ->
155+
t.stats.tx_pkts <- Int32.succ t.stats.tx_pkts;
156+
t.stats.tx_bytes <- Int64.add t.stats.tx_bytes (Int64.of_int len);
157+
if len' <> len then Error (`Partial (t.id, len', buf))
158+
else Ok ())
159+
(fun exn -> Lwt.return (Error (`Exn exn)))
167160

168161
let mac t = t.mac
169162

163+
let mtu t = t.mtu
164+
170165
let get_stats_counters t = t.stats
171166

172167
let reset_stats_counters t =

test/test.ml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,9 @@ let test_close () =
3434

3535
let test_write () =
3636
Netif.connect "tap2" >>= fun t ->
37-
let data = Cstruct.create 4096 in
38-
Netif.writev t [ data ] >>= fun _t ->
39-
Netif.writev t [ data ; (Cstruct.create 14) ] >>= fun _t ->
37+
let mtu = Netif.mtu t in
38+
Netif.write t ~size:mtu (fun _data -> mtu) >>= fun _t ->
39+
Netif.write t ~size:(mtu + 14) (fun _data -> mtu + 14) >>= fun _t ->
4040
Lwt.return_unit
4141

4242
let suite = [

0 commit comments

Comments
 (0)