From 83f0c124b5c90630aba7abb13c0bf415dd097386 Mon Sep 17 00:00:00 2001 From: Hannes Mehnert Date: Thu, 9 May 2024 15:41:09 +0200 Subject: [PATCH 1/4] IP: add get_cidr : t -> cidr list --- src/core/ip.ml | 3 +++ src/core/ip.mli | 13 ++++++++++++- src/ipv4/static_ipv4.ml | 6 ++++++ src/ipv4/static_ipv4.mli | 2 +- src/ipv6/ipv6.ml | 7 +++++++ src/ipv6/ipv6.mli | 2 +- src/ipv6/ndpv6.ml | 7 +++---- src/ipv6/ndpv6.mli | 21 ++++++++++----------- src/stack-direct/tcpip_stack_direct.ml | 11 ++++++++++- src/stack-direct/tcpip_stack_direct.mli | 6 ++++-- src/stack-unix/ipv4_socket.ml | 3 +++ src/stack-unix/ipv4v6_socket.ml | 3 +++ src/stack-unix/ipv6_socket.ml | 3 +++ 13 files changed, 66 insertions(+), 21 deletions(-) diff --git a/src/core/ip.ml b/src/core/ip.ml index a6f4dae5..7d4371c6 100644 --- a/src/core/ip.ml +++ b/src/core/ip.ml @@ -17,6 +17,8 @@ module type S = sig val pp_error: error Fmt.t type ipaddr val pp_ipaddr : ipaddr Fmt.t + type cidr + val pp_cidr : cidr Fmt.t type t val disconnect : t -> unit Lwt.t type callback = src:ipaddr -> dst:ipaddr -> Cstruct.t -> unit Lwt.t @@ -30,5 +32,6 @@ module type S = sig val pseudoheader : t -> ?src:ipaddr -> ipaddr -> proto -> int -> Cstruct.t val src: t -> dst:ipaddr -> ipaddr val get_ip: t -> ipaddr list + val get_cidr: t -> cidr list val mtu: t -> dst:ipaddr -> int end diff --git a/src/core/ip.mli b/src/core/ip.mli index b912ec43..24b1e939 100644 --- a/src/core/ip.mli +++ b/src/core/ip.mli @@ -28,6 +28,12 @@ module type S = sig val pp_ipaddr : ipaddr Fmt.t (** [pp_ipaddr] is the pretty-printer for IP addresses. *) + type cidr + (** The type for the IP address and netmask. *) + + val pp_cidr : cidr Fmt.t + (** [pp_cidr] is the pretty-printer for the CIDR. *) + type t (** The type representing the internal state of the IP layer. *) @@ -78,7 +84,12 @@ module type S = sig val get_ip: t -> ipaddr list (** Get the IP addresses associated with this interface. For IPv4, only one IP address can be set at a time, so the list will always be of - length 1 (and may be the default value, 0.0.0.0). *) + length 1 (and may be the default value, [[10.0.0.2]]). *) + + val get_cidr: t -> cidr list + (** Get the CIDRs associated with this interface. For IPv4, only + one CIDR can be set at a time, so the list will always be of + length 1, e.g. [[10.0.0.2/24]]. *) val mtu: t -> dst:ipaddr -> int (** [mtu ~dst ip] is the Maximum Transmission Unit of the [ip] i.e. the diff --git a/src/ipv4/static_ipv4.ml b/src/ipv4/static_ipv4.ml index 03b96d59..b8a15668 100644 --- a/src/ipv4/static_ipv4.ml +++ b/src/ipv4/static_ipv4.ml @@ -33,6 +33,10 @@ module Make (R: Mirage_random.S) (C: Mirage_clock.MCLOCK) (Ethernet: Ethernet.S) let pp_ipaddr = Ipaddr.V4.pp + type cidr = Ipaddr.V4.Prefix.t + + let pp_cidr = Ipaddr.V4.Prefix.pp + type t = { ethif : Ethernet.t; arp : Arpv4.t; @@ -170,6 +174,8 @@ module Make (R: Mirage_random.S) (C: Mirage_clock.MCLOCK) (Ethernet: Ethernet.S) let get_ip t = [Ipaddr.V4.Prefix.address t.cidr] + let get_cidr t = [t.cidr] + let pseudoheader t ?src dst proto len = let src = match src with None -> Ipaddr.V4.Prefix.address t.cidr | Some x -> x in Ipv4_packet.Marshal.pseudoheader ~src ~dst ~proto len diff --git a/src/ipv4/static_ipv4.mli b/src/ipv4/static_ipv4.mli index 3bcbf32d..ae2ae1ec 100644 --- a/src/ipv4/static_ipv4.mli +++ b/src/ipv4/static_ipv4.mli @@ -15,7 +15,7 @@ *) module Make (R: Mirage_random.S) (C: Mirage_clock.MCLOCK) (E: Ethernet.S) (A: Arp.S) : sig - include Tcpip.Ip.S with type ipaddr = Ipaddr.V4.t + include Tcpip.Ip.S with type ipaddr = Ipaddr.V4.t and type cidr = Ipaddr.V4.Prefix.t val connect : ?no_init:bool -> cidr:Ipaddr.V4.Prefix.t -> ?gateway:Ipaddr.V4.t -> ?fragment_cache_size:int -> E.t -> A.t -> t Lwt.t diff --git a/src/ipv6/ipv6.ml b/src/ipv6/ipv6.ml index c05a95a3..429ec3d6 100644 --- a/src/ipv6/ipv6.ml +++ b/src/ipv6/ipv6.ml @@ -31,6 +31,10 @@ module Make (N : Mirage_net.S) let pp_ipaddr = Ipaddr.V6.pp + type cidr = Ipaddr.V6.Prefix.t + + let pp_cidr = Ipaddr.V6.Prefix.pp + type t = { ethif : E.t; mutable ctx : Ndpv6.context } @@ -114,6 +118,9 @@ module Make (N : Mirage_net.S) let get_ip t = Ndpv6.get_ip t.ctx + let get_cidr t = + Ndpv6.get_prefix t.ctx + let pseudoheader t ?src:source dst proto len = let ph = Cstruct.create (16 + 16 + 8) in let src = match source with None -> src t ~dst | Some x -> x in diff --git a/src/ipv6/ipv6.mli b/src/ipv6/ipv6.mli index 22c85d86..12a0a8bc 100644 --- a/src/ipv6/ipv6.mli +++ b/src/ipv6/ipv6.mli @@ -19,7 +19,7 @@ module Make (N : Mirage_net.S) (R : Mirage_random.S) (T : Mirage_time.S) (Clock : Mirage_clock.MCLOCK) : sig - include Tcpip.Ip.S with type ipaddr = Ipaddr.V6.t + include Tcpip.Ip.S with type ipaddr = Ipaddr.V6.t and type cidr = Ipaddr.V6.Prefix.t val connect : ?no_init:bool -> ?handle_ra:bool -> diff --git a/src/ipv6/ndpv6.ml b/src/ipv6/ndpv6.ml index 72608a0a..91fee875 100644 --- a/src/ipv6/ndpv6.ml +++ b/src/ipv6/ndpv6.ml @@ -41,7 +41,6 @@ module Log = (val Logs.src_log src : Logs.LOG) module Ipaddr = Ipaddr.V6 -type buffer = Cstruct.t type ipaddr = Ipaddr.t type prefix = Ipaddr.Prefix.t type time = int64 @@ -1021,9 +1020,9 @@ module Parser = struct end type event = - [ `Tcp of ipaddr * ipaddr * buffer - | `Udp of ipaddr * ipaddr * buffer - | `Default of int * ipaddr * ipaddr * buffer ] + [ `Tcp of ipaddr * ipaddr * Cstruct.t + | `Udp of ipaddr * ipaddr * Cstruct.t + | `Default of int * ipaddr * ipaddr * Cstruct.t ] (* TODO add destination cache *) type context = diff --git a/src/ipv6/ndpv6.mli b/src/ipv6/ndpv6.mli index ff40cd17..4b911b5d 100644 --- a/src/ipv6/ndpv6.mli +++ b/src/ipv6/ndpv6.mli @@ -14,28 +14,27 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. *) -type buffer = Cstruct.t type ipaddr = Ipaddr.V6.t type prefix = Ipaddr.V6.Prefix.t type time = int64 -val checksum : buffer -> buffer list -> int +val checksum : Cstruct.t -> Cstruct.t list -> int type event = - [ `Tcp of ipaddr * ipaddr * buffer - | `Udp of ipaddr * ipaddr * buffer - | `Default of int * ipaddr * ipaddr * buffer ] + [ `Tcp of ipaddr * ipaddr * Cstruct.t + | `Udp of ipaddr * ipaddr * Cstruct.t + | `Default of int * ipaddr * ipaddr * Cstruct.t ] type context val local : handle_ra:bool -> now:time -> random:(int -> Cstruct.t) -> Macaddr.t -> - context * (Macaddr.t * int * (buffer -> int)) list + context * (Macaddr.t * int * (Cstruct.t -> int)) list (** [local ~handle_ra ~now ~random mac] is a pair [ctx, outs] where [ctx] is a local IPv6 context associated to the hardware address [mac]. [outs] is a list of ethif packets to be sent. *) val add_ip : now:time -> context -> ipaddr -> - context * (Macaddr.t * int * (buffer -> int)) list + context * (Macaddr.t * int * (Cstruct.t -> int)) list (** [add_ip ~now ctx ip] is [ctx', outs] where [ctx'] is [ctx] updated with a new local ip and [outs] is a list of ethif packets to be sent. *) @@ -46,22 +45,22 @@ val select_source : context -> ipaddr -> ipaddr (** [select_source ctx ip] returns the ip that should be put in the source field of a packet destined to [ip]. *) -val handle : now:time -> random:(int -> Cstruct.t) -> context -> buffer -> - context * (Macaddr.t * int * (buffer -> int)) list * event list +val handle : now:time -> random:(int -> Cstruct.t) -> context -> Cstruct.t -> + context * (Macaddr.t * int * (Cstruct.t -> int)) list * event list (** [handle ~now ~random ctx buf] handles an incoming ipv6 packet. It returns [ctx', bufs, evs] where [ctx'] is the updated context, [bufs] is a list of packets to be sent and [evs] is a list of packets to be passed to the higher layers (udp, tcp, etc) for further processing. *) val send : now:time -> context -> ?src:ipaddr -> ipaddr -> Tcpip.Ip.proto -> - int -> (buffer -> buffer -> int) -> context * (Macaddr.t * int * (buffer -> int)) list + int -> (Cstruct.t -> Cstruct.t -> int) -> context * (Macaddr.t * int * (Cstruct.t -> int)) list (** [send ~now ctx ?src dst proto size fillf] starts route resolution and assembles an ipv6 packet of [size] for sending with header and body passed to [fillf]. It returns a pair [ctx', dst_size_fills] where [ctx'] is the updated context and [dst, size, fillf] is a list of packets to be sent, specified by destination, their size, and fill function. *) -val tick : now:time -> context -> context * (Macaddr.t * int * (buffer -> int)) list +val tick : now:time -> context -> context * (Macaddr.t * int * (Cstruct.t -> int)) list (** [tick ~now ctx] should be called periodically (every 1s is good). It returns [ctx', bufs] where [ctx'] is the updated context and [bufs] is a list of packets to be sent. *) diff --git a/src/stack-direct/tcpip_stack_direct.ml b/src/stack-direct/tcpip_stack_direct.ml index 0cf64349..fd9309a0 100644 --- a/src/stack-direct/tcpip_stack_direct.ml +++ b/src/stack-direct/tcpip_stack_direct.ml @@ -19,13 +19,18 @@ open Lwt.Infix let src = Logs.Src.create "tcpip-stack-direct" ~doc:"Pure OCaml TCP/IP stack" module Log = (val Logs.src_log src : Logs.LOG) -module IPV4V6 (Ipv4 : Tcpip.Ip.S with type ipaddr = Ipaddr.V4.t) (Ipv6 : Tcpip.Ip.S with type ipaddr = Ipaddr.V6.t) = struct +module IPV4V6 + (Ipv4 : Tcpip.Ip.S with type ipaddr = Ipaddr.V4.t and type cidr = Ipaddr.V4.Prefix.t) + (Ipv6 : Tcpip.Ip.S with type ipaddr = Ipaddr.V6.t and type cidr = Ipaddr.V6.Prefix.t) = struct type ipaddr = Ipaddr.t type callback = src:ipaddr -> dst:ipaddr -> Cstruct.t -> unit Lwt.t let pp_ipaddr = Ipaddr.pp + type cidr = Ipaddr.Prefix.t + let pp_cidr = Ipaddr.Prefix.pp + type error = [ Tcpip.Ip.error | `Ipv4 of Ipv4.error | `Ipv6 of Ipv6.error | `Msg of string ] let pp_error ppf = function @@ -129,6 +134,10 @@ module IPV4V6 (Ipv4 : Tcpip.Ip.S with type ipaddr = Ipaddr.V4.t) (Ipv6 : Tcpip.I List.map (fun ip -> Ipaddr.V4 ip) (Ipv4.get_ip t.ipv4) @ List.map (fun ip -> Ipaddr.V6 ip) (Ipv6.get_ip t.ipv6) + let get_cidr t = + List.map (fun cidr -> Ipaddr.V4 cidr) (Ipv4.get_cidr t.ipv4) @ + List.map (fun cidr -> Ipaddr.V6 cidr) (Ipv6.get_cidr t.ipv6) + let mtu t ~dst = match dst with | Ipaddr.V4 dst -> Ipv4.mtu t.ipv4 ~dst | Ipaddr.V6 dst -> Ipv6.mtu t.ipv6 ~dst diff --git a/src/stack-direct/tcpip_stack_direct.mli b/src/stack-direct/tcpip_stack_direct.mli index d0e9f37c..de6bfddf 100644 --- a/src/stack-direct/tcpip_stack_direct.mli +++ b/src/stack-direct/tcpip_stack_direct.mli @@ -14,8 +14,10 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. *) -module IPV4V6 (Ipv4 : Tcpip.Ip.S with type ipaddr = Ipaddr.V4.t) (Ipv6 : Tcpip.Ip.S with type ipaddr = Ipaddr.V6.t) : sig - include Tcpip.Ip.S with type ipaddr = Ipaddr.t +module IPV4V6 + (Ipv4 : Tcpip.Ip.S with type ipaddr = Ipaddr.V4.t and type cidr = Ipaddr.V4.Prefix.t) + (Ipv6 : Tcpip.Ip.S with type ipaddr = Ipaddr.V6.t and type cidr = Ipaddr.V6.Prefix.t) : sig + include Tcpip.Ip.S with type ipaddr = Ipaddr.t and type cidr = Ipaddr.Prefix.t val connect : ipv4_only:bool -> ipv6_only:bool -> Ipv4.t -> Ipv6.t -> t Lwt.t end diff --git a/src/stack-unix/ipv4_socket.ml b/src/stack-unix/ipv4_socket.ml index 8286638a..029516b5 100644 --- a/src/stack-unix/ipv4_socket.ml +++ b/src/stack-unix/ipv4_socket.ml @@ -18,9 +18,11 @@ type t = unit type error = Tcpip.Ip.error type ipaddr = Ipaddr.V4.t type callback = src:ipaddr -> dst:ipaddr -> Cstruct.t -> unit Lwt.t +type cidr = Ipaddr.V4.Prefix.t let pp_error = Tcpip.Ip.pp_error let pp_ipaddr = Ipaddr.V4.pp +let pp_cidr = Ipaddr.V4.Prefix.pp let mtu _ ~dst:_ = 1500 - Ipv4_wire.sizeof_ipv4 @@ -32,5 +34,6 @@ let write _ ?fragment:_ ?ttl:_ ?src:_ _ _ ?size:_ _ _ = Lwt.fail (Failure "Not implemented") let get_ip _ = [Ipaddr.V4.any] +let get_cidr _ = [Ipaddr.V4.Prefix.global] let src _ ~dst:_ = raise (Failure "Not implemented") let pseudoheader _ ?src:_ _ _ _ = raise (Failure "Not implemented") diff --git a/src/stack-unix/ipv4v6_socket.ml b/src/stack-unix/ipv4v6_socket.ml index 1b355980..0f15ef37 100644 --- a/src/stack-unix/ipv4v6_socket.ml +++ b/src/stack-unix/ipv4v6_socket.ml @@ -18,9 +18,11 @@ type t = unit type error = Tcpip.Ip.error type ipaddr = Ipaddr.t type callback = src:ipaddr -> dst:ipaddr -> Cstruct.t -> unit Lwt.t +type cidr = Ipaddr.Prefix.t let pp_error = Tcpip.Ip.pp_error let pp_ipaddr = Ipaddr.pp +let pp_cidr = Ipaddr.Prefix.pp let mtu _ ~dst = match dst with | Ipaddr.V4 _ -> 1500 - Ipv4_wire.sizeof_ipv4 @@ -34,5 +36,6 @@ let write _ ?fragment:_ ?ttl:_ ?src:_ _ _ ?size:_ _ _ = Lwt.fail (Failure "Not implemented") let get_ip _ = [Ipaddr.V6 Ipaddr.V6.unspecified] +let get_cidr _ = [Ipaddr.Prefix.of_string_exn "::/0"] let src _ ~dst:_ = raise (Failure "Not implemented") let pseudoheader _ ?src:_ _ _ _ = raise (Failure "Not implemented") diff --git a/src/stack-unix/ipv6_socket.ml b/src/stack-unix/ipv6_socket.ml index 2d1e7c54..fda754cb 100644 --- a/src/stack-unix/ipv6_socket.ml +++ b/src/stack-unix/ipv6_socket.ml @@ -19,9 +19,11 @@ type t = unit type error = Tcpip.Ip.error type ipaddr = Ipaddr.V6.t type callback = src:ipaddr -> dst:ipaddr -> Cstruct.t -> unit Lwt.t +type cidr = Ipaddr.V6.Prefix.t let pp_error = Tcpip.Ip.pp_error let pp_ipaddr = Ipaddr.V6.pp +let pp_cidr = Ipaddr.V6.Prefix.pp let mtu _ ~dst:_ = 1500 - Ipv6_wire.sizeof_ipv6 @@ -33,5 +35,6 @@ let write _ ?fragment:_ ?ttl:_ ?src:_ _ _ ?size:_ _ _ = Lwt.fail (Failure "Not implemented") let get_ip _ = [Ipaddr.V6.unspecified] +let get_cidr _ = [Ipaddr.V6.Prefix.of_string_exn "::/0"] let src _ ~dst:_ = raise (Failure "Not implemented") let pseudoheader _ ?src:_ _ _ _ = raise (Failure "Not implemented") From 2f45917b25722f58f441527daf398b6807c6d988 Mon Sep 17 00:00:00 2001 From: Hannes Mehnert Date: Wed, 22 May 2024 12:30:57 +0200 Subject: [PATCH 2/4] Add the function IP.configured_ips : t -> prefix list Mark get_ips as deprecated, use configured_ips across this package. Also carry the type equality for 'type prefix' across. --- src/core/ip.ml | 7 ++++--- src/core/ip.mli | 13 +++++++------ src/core/stack.ml | 2 +- src/ipv4/static_ipv4.ml | 6 +++--- src/ipv4/static_ipv4.mli | 2 +- src/ipv6/ipv6.ml | 6 +++--- src/ipv6/ipv6.mli | 2 +- src/stack-direct/tcpip_stack_direct.ml | 18 ++++++++++-------- src/stack-direct/tcpip_stack_direct.mli | 8 ++++---- src/stack-unix/ipv4_socket.ml | 6 +++--- src/stack-unix/ipv4v6_socket.ml | 6 +++--- src/stack-unix/ipv6_socket.ml | 6 +++--- src/tcp/flow.ml | 6 ++++-- src/udp/udp.ml | 6 ++++-- tcpip.opam | 2 +- test/test_deadlock.ml | 1 - test/test_iperf.ml | 4 ++-- test/test_iperf_ipv6.ml | 4 ++-- test/vnetif_common.ml | 2 -- 19 files changed, 56 insertions(+), 51 deletions(-) diff --git a/src/core/ip.ml b/src/core/ip.ml index 7d4371c6..ce324c67 100644 --- a/src/core/ip.ml +++ b/src/core/ip.ml @@ -17,8 +17,8 @@ module type S = sig val pp_error: error Fmt.t type ipaddr val pp_ipaddr : ipaddr Fmt.t - type cidr - val pp_cidr : cidr Fmt.t + type prefix + val pp_prefix : prefix Fmt.t type t val disconnect : t -> unit Lwt.t type callback = src:ipaddr -> dst:ipaddr -> Cstruct.t -> unit Lwt.t @@ -32,6 +32,7 @@ module type S = sig val pseudoheader : t -> ?src:ipaddr -> ipaddr -> proto -> int -> Cstruct.t val src: t -> dst:ipaddr -> ipaddr val get_ip: t -> ipaddr list - val get_cidr: t -> cidr list + [@@ocaml.deprecated "this function will be removed soon, use [configured_ips] instead."] + val configured_ips: t -> prefix list val mtu: t -> dst:ipaddr -> int end diff --git a/src/core/ip.mli b/src/core/ip.mli index 24b1e939..1ccbaee1 100644 --- a/src/core/ip.mli +++ b/src/core/ip.mli @@ -28,11 +28,11 @@ module type S = sig val pp_ipaddr : ipaddr Fmt.t (** [pp_ipaddr] is the pretty-printer for IP addresses. *) - type cidr + type prefix (** The type for the IP address and netmask. *) - val pp_cidr : cidr Fmt.t - (** [pp_cidr] is the pretty-printer for the CIDR. *) + val pp_prefix : prefix Fmt.t + (** [pp_prefix] is the pretty-printer for the prefix. *) type t (** The type representing the internal state of the IP layer. *) @@ -82,13 +82,14 @@ module type S = sig the same IP, which is the only one set. *) val get_ip: t -> ipaddr list + [@@ocaml.deprecated "this function will be removed soon, use [configured_ips] instead."] (** Get the IP addresses associated with this interface. For IPv4, only one IP address can be set at a time, so the list will always be of length 1 (and may be the default value, [[10.0.0.2]]). *) - val get_cidr: t -> cidr list - (** Get the CIDRs associated with this interface. For IPv4, only - one CIDR can be set at a time, so the list will always be of + val configured_ips: t -> prefix list + (** Get the prefix associated with this interface. For IPv4, only + one prefix can be set at a time, so the list will always be of length 1, e.g. [[10.0.0.2/24]]. *) val mtu: t -> dst:ipaddr -> int diff --git a/src/core/stack.ml b/src/core/stack.ml index a8a8b5a4..230106d4 100644 --- a/src/core/stack.ml +++ b/src/core/stack.ml @@ -10,7 +10,7 @@ module type V4V6 = sig module TCP: Tcp.S with type ipaddr = Ipaddr.t - module IP: Ip.S with type ipaddr = Ipaddr.t + module IP: Ip.S with type ipaddr = Ipaddr.t and type prefix = Ipaddr.Prefix.t val udp: t -> UDP.t (** [udp t] obtains a descriptor for use with the [UDP] module, diff --git a/src/ipv4/static_ipv4.ml b/src/ipv4/static_ipv4.ml index b8a15668..1b9065d7 100644 --- a/src/ipv4/static_ipv4.ml +++ b/src/ipv4/static_ipv4.ml @@ -33,9 +33,9 @@ module Make (R: Mirage_random.S) (C: Mirage_clock.MCLOCK) (Ethernet: Ethernet.S) let pp_ipaddr = Ipaddr.V4.pp - type cidr = Ipaddr.V4.Prefix.t + type prefix = Ipaddr.V4.Prefix.t - let pp_cidr = Ipaddr.V4.Prefix.pp + let pp_prefix = Ipaddr.V4.Prefix.pp type t = { ethif : Ethernet.t; @@ -174,7 +174,7 @@ module Make (R: Mirage_random.S) (C: Mirage_clock.MCLOCK) (Ethernet: Ethernet.S) let get_ip t = [Ipaddr.V4.Prefix.address t.cidr] - let get_cidr t = [t.cidr] + let configured_ips t = [t.cidr] let pseudoheader t ?src dst proto len = let src = match src with None -> Ipaddr.V4.Prefix.address t.cidr | Some x -> x in diff --git a/src/ipv4/static_ipv4.mli b/src/ipv4/static_ipv4.mli index ae2ae1ec..603873b2 100644 --- a/src/ipv4/static_ipv4.mli +++ b/src/ipv4/static_ipv4.mli @@ -15,7 +15,7 @@ *) module Make (R: Mirage_random.S) (C: Mirage_clock.MCLOCK) (E: Ethernet.S) (A: Arp.S) : sig - include Tcpip.Ip.S with type ipaddr = Ipaddr.V4.t and type cidr = Ipaddr.V4.Prefix.t + include Tcpip.Ip.S with type ipaddr = Ipaddr.V4.t and type prefix = Ipaddr.V4.Prefix.t val connect : ?no_init:bool -> cidr:Ipaddr.V4.Prefix.t -> ?gateway:Ipaddr.V4.t -> ?fragment_cache_size:int -> E.t -> A.t -> t Lwt.t diff --git a/src/ipv6/ipv6.ml b/src/ipv6/ipv6.ml index 429ec3d6..6a82bea6 100644 --- a/src/ipv6/ipv6.ml +++ b/src/ipv6/ipv6.ml @@ -31,9 +31,9 @@ module Make (N : Mirage_net.S) let pp_ipaddr = Ipaddr.V6.pp - type cidr = Ipaddr.V6.Prefix.t + type prefix = Ipaddr.V6.Prefix.t - let pp_cidr = Ipaddr.V6.Prefix.pp + let pp_prefix = Ipaddr.V6.Prefix.pp type t = { ethif : E.t; @@ -118,7 +118,7 @@ module Make (N : Mirage_net.S) let get_ip t = Ndpv6.get_ip t.ctx - let get_cidr t = + let configured_ips t = Ndpv6.get_prefix t.ctx let pseudoheader t ?src:source dst proto len = diff --git a/src/ipv6/ipv6.mli b/src/ipv6/ipv6.mli index 12a0a8bc..33aac241 100644 --- a/src/ipv6/ipv6.mli +++ b/src/ipv6/ipv6.mli @@ -19,7 +19,7 @@ module Make (N : Mirage_net.S) (R : Mirage_random.S) (T : Mirage_time.S) (Clock : Mirage_clock.MCLOCK) : sig - include Tcpip.Ip.S with type ipaddr = Ipaddr.V6.t and type cidr = Ipaddr.V6.Prefix.t + include Tcpip.Ip.S with type ipaddr = Ipaddr.V6.t and type prefix = Ipaddr.V6.Prefix.t val connect : ?no_init:bool -> ?handle_ra:bool -> diff --git a/src/stack-direct/tcpip_stack_direct.ml b/src/stack-direct/tcpip_stack_direct.ml index fd9309a0..fd9e4968 100644 --- a/src/stack-direct/tcpip_stack_direct.ml +++ b/src/stack-direct/tcpip_stack_direct.ml @@ -20,16 +20,16 @@ let src = Logs.Src.create "tcpip-stack-direct" ~doc:"Pure OCaml TCP/IP stack" module Log = (val Logs.src_log src : Logs.LOG) module IPV4V6 - (Ipv4 : Tcpip.Ip.S with type ipaddr = Ipaddr.V4.t and type cidr = Ipaddr.V4.Prefix.t) - (Ipv6 : Tcpip.Ip.S with type ipaddr = Ipaddr.V6.t and type cidr = Ipaddr.V6.Prefix.t) = struct + (Ipv4 : Tcpip.Ip.S with type ipaddr = Ipaddr.V4.t and type prefix = Ipaddr.V4.Prefix.t) + (Ipv6 : Tcpip.Ip.S with type ipaddr = Ipaddr.V6.t and type prefix = Ipaddr.V6.Prefix.t) = struct type ipaddr = Ipaddr.t type callback = src:ipaddr -> dst:ipaddr -> Cstruct.t -> unit Lwt.t let pp_ipaddr = Ipaddr.pp - type cidr = Ipaddr.Prefix.t - let pp_cidr = Ipaddr.Prefix.pp + type prefix = Ipaddr.Prefix.t + let pp_prefix = Ipaddr.Prefix.pp type error = [ Tcpip.Ip.error | `Ipv4 of Ipv4.error | `Ipv6 of Ipv6.error | `Msg of string ] @@ -130,13 +130,15 @@ module IPV4V6 | Ipaddr.V4 dst -> Ipaddr.V4 (Ipv4.src t.ipv4 ~dst) | Ipaddr.V6 dst -> Ipaddr.V6 (Ipv6.src t.ipv6 ~dst) + [@@@alert "-deprecated"] let get_ip t = List.map (fun ip -> Ipaddr.V4 ip) (Ipv4.get_ip t.ipv4) @ List.map (fun ip -> Ipaddr.V6 ip) (Ipv6.get_ip t.ipv6) + [@@@alert "+deprecated"] - let get_cidr t = - List.map (fun cidr -> Ipaddr.V4 cidr) (Ipv4.get_cidr t.ipv4) @ - List.map (fun cidr -> Ipaddr.V6 cidr) (Ipv6.get_cidr t.ipv6) + let configured_ips t = + List.map (fun cidr -> Ipaddr.V4 cidr) (Ipv4.configured_ips t.ipv4) @ + List.map (fun cidr -> Ipaddr.V6 cidr) (Ipv6.configured_ips t.ipv6) let mtu t ~dst = match dst with | Ipaddr.V4 dst -> Ipv4.mtu t.ipv4 ~dst @@ -171,7 +173,7 @@ module MakeV4V6 let pp fmt t = Format.fprintf fmt "mac=%a,ip=%a" Macaddr.pp (Eth.mac t.ethif) - Fmt.(list ~sep:(any ", ") Ipaddr.pp) (IP.get_ip t.ip) + Fmt.(list ~sep:(any ", ") IP.pp_prefix) (IP.configured_ips t.ip) let tcp { tcp; _ } = tcp let udp { udp; _ } = udp diff --git a/src/stack-direct/tcpip_stack_direct.mli b/src/stack-direct/tcpip_stack_direct.mli index de6bfddf..e2b4d634 100644 --- a/src/stack-direct/tcpip_stack_direct.mli +++ b/src/stack-direct/tcpip_stack_direct.mli @@ -15,9 +15,9 @@ *) module IPV4V6 - (Ipv4 : Tcpip.Ip.S with type ipaddr = Ipaddr.V4.t and type cidr = Ipaddr.V4.Prefix.t) - (Ipv6 : Tcpip.Ip.S with type ipaddr = Ipaddr.V6.t and type cidr = Ipaddr.V6.Prefix.t) : sig - include Tcpip.Ip.S with type ipaddr = Ipaddr.t and type cidr = Ipaddr.Prefix.t + (Ipv4 : Tcpip.Ip.S with type ipaddr = Ipaddr.V4.t and type prefix = Ipaddr.V4.Prefix.t) + (Ipv6 : Tcpip.Ip.S with type ipaddr = Ipaddr.V6.t and type prefix = Ipaddr.V6.Prefix.t) : sig + include Tcpip.Ip.S with type ipaddr = Ipaddr.t and type prefix = Ipaddr.Prefix.t val connect : ipv4_only:bool -> ipv6_only:bool -> Ipv4.t -> Ipv6.t -> t Lwt.t end @@ -28,7 +28,7 @@ module MakeV4V6 (Netif : Mirage_net.S) (Ethernet : Ethernet.S) (Arpv4 : Arp.S) - (Ip : Tcpip.Ip.S with type ipaddr = Ipaddr.t) + (Ip : Tcpip.Ip.S with type ipaddr = Ipaddr.t and type prefix = Ipaddr.Prefix.t) (Icmpv4 : Icmpv4.S) (Udp : Tcpip.Udp.S with type ipaddr = Ipaddr.t) (Tcp : Tcpip.Tcp.S with type ipaddr = Ipaddr.t) : sig diff --git a/src/stack-unix/ipv4_socket.ml b/src/stack-unix/ipv4_socket.ml index 029516b5..9108eb9b 100644 --- a/src/stack-unix/ipv4_socket.ml +++ b/src/stack-unix/ipv4_socket.ml @@ -18,11 +18,11 @@ type t = unit type error = Tcpip.Ip.error type ipaddr = Ipaddr.V4.t type callback = src:ipaddr -> dst:ipaddr -> Cstruct.t -> unit Lwt.t -type cidr = Ipaddr.V4.Prefix.t +type prefix = Ipaddr.V4.Prefix.t let pp_error = Tcpip.Ip.pp_error let pp_ipaddr = Ipaddr.V4.pp -let pp_cidr = Ipaddr.V4.Prefix.pp +let pp_prefix = Ipaddr.V4.Prefix.pp let mtu _ ~dst:_ = 1500 - Ipv4_wire.sizeof_ipv4 @@ -34,6 +34,6 @@ let write _ ?fragment:_ ?ttl:_ ?src:_ _ _ ?size:_ _ _ = Lwt.fail (Failure "Not implemented") let get_ip _ = [Ipaddr.V4.any] -let get_cidr _ = [Ipaddr.V4.Prefix.global] +let configured_ips _ = [Ipaddr.V4.Prefix.global] let src _ ~dst:_ = raise (Failure "Not implemented") let pseudoheader _ ?src:_ _ _ _ = raise (Failure "Not implemented") diff --git a/src/stack-unix/ipv4v6_socket.ml b/src/stack-unix/ipv4v6_socket.ml index 0f15ef37..64a04c01 100644 --- a/src/stack-unix/ipv4v6_socket.ml +++ b/src/stack-unix/ipv4v6_socket.ml @@ -18,11 +18,11 @@ type t = unit type error = Tcpip.Ip.error type ipaddr = Ipaddr.t type callback = src:ipaddr -> dst:ipaddr -> Cstruct.t -> unit Lwt.t -type cidr = Ipaddr.Prefix.t +type prefix = Ipaddr.Prefix.t let pp_error = Tcpip.Ip.pp_error let pp_ipaddr = Ipaddr.pp -let pp_cidr = Ipaddr.Prefix.pp +let pp_prefix = Ipaddr.Prefix.pp let mtu _ ~dst = match dst with | Ipaddr.V4 _ -> 1500 - Ipv4_wire.sizeof_ipv4 @@ -36,6 +36,6 @@ let write _ ?fragment:_ ?ttl:_ ?src:_ _ _ ?size:_ _ _ = Lwt.fail (Failure "Not implemented") let get_ip _ = [Ipaddr.V6 Ipaddr.V6.unspecified] -let get_cidr _ = [Ipaddr.Prefix.of_string_exn "::/0"] +let configured_ips _ = [Ipaddr.Prefix.of_string_exn "::/0"] let src _ ~dst:_ = raise (Failure "Not implemented") let pseudoheader _ ?src:_ _ _ _ = raise (Failure "Not implemented") diff --git a/src/stack-unix/ipv6_socket.ml b/src/stack-unix/ipv6_socket.ml index fda754cb..76a068fe 100644 --- a/src/stack-unix/ipv6_socket.ml +++ b/src/stack-unix/ipv6_socket.ml @@ -19,11 +19,11 @@ type t = unit type error = Tcpip.Ip.error type ipaddr = Ipaddr.V6.t type callback = src:ipaddr -> dst:ipaddr -> Cstruct.t -> unit Lwt.t -type cidr = Ipaddr.V6.Prefix.t +type prefix = Ipaddr.V6.Prefix.t let pp_error = Tcpip.Ip.pp_error let pp_ipaddr = Ipaddr.V6.pp -let pp_cidr = Ipaddr.V6.Prefix.pp +let pp_prefix = Ipaddr.V6.Prefix.pp let mtu _ ~dst:_ = 1500 - Ipv6_wire.sizeof_ipv6 @@ -35,6 +35,6 @@ let write _ ?fragment:_ ?ttl:_ ?src:_ _ _ ?size:_ _ _ = Lwt.fail (Failure "Not implemented") let get_ip _ = [Ipaddr.V6.unspecified] -let get_cidr _ = [Ipaddr.V6.Prefix.of_string_exn "::/0"] +let configured_ips _ = [Ipaddr.V6.Prefix.of_string_exn "::/0"] let src _ ~dst:_ = raise (Failure "Not implemented") let pseudoheader _ ?src:_ _ _ _ = raise (Failure "Not implemented") diff --git a/src/tcp/flow.ml b/src/tcp/flow.ml index 10107ba6..a1ccf9d5 100644 --- a/src/tcp/flow.ml +++ b/src/tcp/flow.ml @@ -757,13 +757,15 @@ struct let connects = Hashtbl.create 1 in let channels = Hashtbl.create 7 in Log.info (fun f -> f "TCP layer connected on %a" - Fmt.(list ~sep:(any ", ") Ip.pp_ipaddr) @@ Ip.get_ip ip); + Fmt.(list ~sep:(any ", ") Ip.pp_prefix) + (Ip.configured_ips ip)); Lwt.return { ip; listeners = Hashtbl.create 7; active = true; localport; channels; listens; connects } let disconnect t = t.active <- false; Log.info (fun f -> f "TCP layer disconnected on %a" - Fmt.(list ~sep:(any ", ") Ip.pp_ipaddr) @@ Ip.get_ip t.ip); + Fmt.(list ~sep:(any ", ") Ip.pp_prefix) + (Ip.configured_ips t.ip)); let conns = Hashtbl.fold (fun _ (pcb, _) acc -> pcb :: acc) t.channels [] in Lwt_list.iter_p close conns >|= fun () -> Hashtbl.reset t.listens; diff --git a/src/udp/udp.ml b/src/udp/udp.ml index 1031bccc..347b681f 100644 --- a/src/udp/udp.ml +++ b/src/udp/udp.ml @@ -86,13 +86,15 @@ module Make (Ip : Tcpip.Ip.S) (Random : Mirage_random.S) = struct let connect ip = Log.info (fun f -> f "UDP layer connected on %a" - Fmt.(list ~sep:(any ", ") Ip.pp_ipaddr) @@ Ip.get_ip ip); + Fmt.(list ~sep:(any ", ") Ip.pp_prefix) + (Ip.configured_ips ip)); let t = { ip ; listeners = Hashtbl.create 7 } in Lwt.return t let disconnect t = Log.info (fun f -> f "UDP layer disconnected on %a" - Fmt.(list ~sep:(any ", ") Ip.pp_ipaddr) @@ Ip.get_ip t.ip); + Fmt.(list ~sep:(any ", ") Ip.pp_prefix) + (Ip.configured_ips t.ip)); Lwt.return_unit end diff --git a/tcpip.opam b/tcpip.opam index 0796f407..2a504876 100644 --- a/tcpip.opam +++ b/tcpip.opam @@ -32,7 +32,7 @@ depends: [ "mirage-clock" {>= "3.0.0"} "mirage-random" {>= "2.0.0" & < "4.0.0"} "mirage-time" {>= "2.0.0"} - "ipaddr" {>= "5.0.0"} + "ipaddr" {>= "5.6.0"} "macaddr" {>="4.0.0"} "macaddr-cstruct" "fmt" {>= "0.8.7"} diff --git a/test/test_deadlock.ml b/test/test_deadlock.ml index 0021412c..d7efd616 100644 --- a/test/test_deadlock.ml +++ b/test/test_deadlock.ml @@ -14,7 +14,6 @@ struct module TIME = struct - type 'a io = 'a Lwt.t let sleep_ns nanos = Lwt_unix.sleep (Int64.to_float nanos /. 1e9) end diff --git a/test/test_iperf.ml b/test/test_iperf.ml index e908b5ab..5fb58c07 100644 --- a/test/test_iperf.ml +++ b/test/test_iperf.ml @@ -164,7 +164,7 @@ module Test_iperf (B : Vnetif_backends.Backend) = struct let server_done, server_done_u = Lwt.wait () in let server_s, client_s = server, client in - let ip_of s = V.Stack.IP.get_ip (V.Stack.ip s) |> List.hd in + let ip_of s = V.Stack.ip s |> V.Stack.IP.configured_ips |> List.hd |> Ipaddr.Prefix.address in Lwt.pick [ (Lwt_unix.sleep timeout >>= fun () -> (* timeout *) @@ -178,7 +178,7 @@ module Test_iperf (B : Vnetif_backends.Backend) = struct iperfclient client_s amt (ip_of server) port); (Logs.info (fun f -> f "I am server with IP %a, expecting connections on port %d" - Ipaddr.pp (V.Stack.IP.get_ip (V.Stack.ip server_s) |> List.hd) + V.Stack.IP.pp_prefix (V.Stack.IP.configured_ips (V.Stack.ip server_s) |> List.hd) port); V.Stack.TCP.listen (V.Stack.tcp server_s) ~port (iperf server_s server_done_u); Lwt.wakeup server_ready_u (); diff --git a/test/test_iperf_ipv6.ml b/test/test_iperf_ipv6.ml index f0b3f640..10b42162 100644 --- a/test/test_iperf_ipv6.ml +++ b/test/test_iperf_ipv6.ml @@ -167,7 +167,7 @@ module Test_iperf_ipv6 (B : Vnetif_backends.Backend) = struct let server_done, server_done_u = Lwt.wait () in let server_s, client_s = server, client in - let ip_of s = V.Stack.IP.get_ip (V.Stack.ip s) |> List.rev |> List.hd in + let ip_of s = V.Stack.ip s |> V.Stack.IP.configured_ips |> List.rev |> List.hd |> Ipaddr.Prefix.address in Lwt.pick [ (Lwt_unix.sleep timeout >>= fun () -> (* timeout *) @@ -181,7 +181,7 @@ module Test_iperf_ipv6 (B : Vnetif_backends.Backend) = struct iperfclient client_s amt (ip_of server) port); (Logs.info (fun f -> f "I am server with IP %a, expecting connections on port %d" - Ipaddr.pp (V.Stack.IP.get_ip (V.Stack.ip server_s) |> List.hd) + V.Stack.IP.pp_prefix (V.Stack.IP.configured_ips (V.Stack.ip server_s) |> List.hd) port); V.Stack.TCP.listen (V.Stack.tcp server_s) ~port (iperf server_s server_done_u); Lwt.wakeup server_ready_u (); diff --git a/test/vnetif_common.ml b/test/vnetif_common.ml index 702292ec..838d46ce 100644 --- a/test/vnetif_common.ml +++ b/test/vnetif_common.ml @@ -21,7 +21,6 @@ open Lwt.Infix to mirage-vnetif *) module Time = struct - type 'a io = 'a Lwt.t include Lwt_unix let sleep_ns ns = sleep (Duration.to_f ns) end @@ -59,7 +58,6 @@ module VNETIF_STACK (B: Vnetif_backends.Backend): sig end = struct type backend = B.t - module V = Vnetif.Make(B) module E = Ethernet.Make(V) From e4df0cb04844edb7362083b9aa40eb365cbc441b Mon Sep 17 00:00:00 2001 From: Hannes Mehnert Date: Fri, 24 May 2024 15:48:49 +0200 Subject: [PATCH 3/4] iperf test: try another path of figuring out the ips --- test/test_iperf.ml | 6 +++++- test/test_iperf_ipv6.ml | 6 +++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/test/test_iperf.ml b/test/test_iperf.ml index 5fb58c07..133a5e96 100644 --- a/test/test_iperf.ml +++ b/test/test_iperf.ml @@ -164,7 +164,11 @@ module Test_iperf (B : Vnetif_backends.Backend) = struct let server_done, server_done_u = Lwt.wait () in let server_s, client_s = server, client in - let ip_of s = V.Stack.ip s |> V.Stack.IP.configured_ips |> List.hd |> Ipaddr.Prefix.address in + let ip_of s = + V.Stack.ip s |> V.Stack.IP.configured_ips |> + List.filter (function Ipaddr.V4 _ -> true | Ipaddr.V6 _ -> false) |> + List.hd |> Ipaddr.Prefix.address + in Lwt.pick [ (Lwt_unix.sleep timeout >>= fun () -> (* timeout *) diff --git a/test/test_iperf_ipv6.ml b/test/test_iperf_ipv6.ml index 10b42162..6510199a 100644 --- a/test/test_iperf_ipv6.ml +++ b/test/test_iperf_ipv6.ml @@ -167,7 +167,11 @@ module Test_iperf_ipv6 (B : Vnetif_backends.Backend) = struct let server_done, server_done_u = Lwt.wait () in let server_s, client_s = server, client in - let ip_of s = V.Stack.ip s |> V.Stack.IP.configured_ips |> List.rev |> List.hd |> Ipaddr.Prefix.address in + let ip_of s = + V.Stack.ip s |> V.Stack.IP.configured_ips |> + List.filter (function Ipaddr.V4 _ -> false | Ipaddr.V6 _ -> true) |> + List.rev |> List.hd |> Ipaddr.Prefix.address + in Lwt.pick [ (Lwt_unix.sleep timeout >>= fun () -> (* timeout *) From 4250473d96751294ca1e1d16660642eed2befaed Mon Sep 17 00:00:00 2001 From: Hannes Mehnert Date: Fri, 24 May 2024 16:13:18 +0200 Subject: [PATCH 4/4] ipv6: actually preserve and expose Ipaddr.Prefix.t, not only Ipaddr.t --- src/ipv6/ipv6.ml | 4 ++-- src/ipv6/ndpv6.ml | 58 +++++++++++++++++++++++++--------------------- src/ipv6/ndpv6.mli | 5 +++- 3 files changed, 38 insertions(+), 29 deletions(-) diff --git a/src/ipv6/ipv6.ml b/src/ipv6/ipv6.ml index 6a82bea6..37ddbd43 100644 --- a/src/ipv6/ipv6.ml +++ b/src/ipv6/ipv6.ml @@ -119,7 +119,7 @@ module Make (N : Mirage_net.S) Ndpv6.get_ip t.ctx let configured_ips t = - Ndpv6.get_prefix t.ctx + Ndpv6.configured_ips t.ctx let pseudoheader t ?src:source dst proto len = let ph = Cstruct.create (16 + 16 + 8) in @@ -140,7 +140,7 @@ module Make (N : Mirage_net.S) let ctx, outs = match cidr with | None -> ctx, outs | Some p -> - let ctx, outs' = Ndpv6.add_ip ~now ctx (Ipaddr.V6.Prefix.address p) in + let ctx, outs' = Ndpv6.add_ip ~now ctx p in let ctx = Ndpv6.add_prefix ~now ctx (Ipaddr.V6.Prefix.prefix p) in ctx, outs @ outs' in diff --git a/src/ipv6/ndpv6.ml b/src/ipv6/ndpv6.ml index 91fee875..effc6688 100644 --- a/src/ipv6/ndpv6.ml +++ b/src/ipv6/ndpv6.ml @@ -105,7 +105,8 @@ let interface_addr mac = (c 4 lsl 8 + c 5) let link_local_addr mac = - Ipaddr.(Prefix.network_address Prefix.link (interface_addr mac)) + let addr = Ipaddr.(Prefix.network_address Prefix.link (interface_addr mac)) in + Ipaddr.Prefix.(make (bits link) addr) let multicast_mac = let pbuf = Cstruct.create 6 in @@ -271,7 +272,7 @@ module AddressList = struct | DEPRECATED of time option type t = - (Ipaddr.t * state) list + (Ipaddr.Prefix.t * state) list let empty = [] @@ -287,37 +288,41 @@ module AddressList = struct let select_source al ~dst:_ = let rec loop = function | (_, TENTATIVE _) :: rest -> loop rest - | (ip, _) :: _ -> ip (* FIXME *) + | (ip, _) :: _ -> Ipaddr.Prefix.address ip (* FIXME *) | [] -> Ipaddr.unspecified in loop al let tick_one ~now ~retrans_timer = function - | (ip, TENTATIVE (timeout, n, t)) when t <= now -> + | (prefix, TENTATIVE (timeout, n, t)) when t <= now -> if n + 1 >= Defaults.dup_addr_detect_transmits then let timeout = match timeout with | None -> None | Some (preferred_lifetime, valid_lifetime) -> Some (Int64.add now preferred_lifetime, valid_lifetime) in + let ip = Ipaddr.Prefix.address prefix in Log.debug (fun f -> f "SLAAC: %a --> PREFERRED" Ipaddr.pp ip); - Some (ip, PREFERRED timeout), [] + Some (prefix, PREFERRED timeout), [] else + let ip = Ipaddr.Prefix.address prefix in let dst = Ipaddr.Prefix.network_address solicited_node_prefix ip in - Some (ip, TENTATIVE (timeout, n+1, Int64.add now retrans_timer)), + Some (prefix, TENTATIVE (timeout, n+1, Int64.add now retrans_timer)), [SendNS (`Unspecified, dst, ip)] - | ip, PREFERRED (Some (preferred_timeout, valid_lifetime)) when preferred_timeout <= now -> + | prefix, PREFERRED (Some (preferred_timeout, valid_lifetime)) when preferred_timeout <= now -> + let ip = Ipaddr.Prefix.address prefix in Log.debug (fun f -> f "SLAAC: %a --> DEPRECATED" Ipaddr.pp ip); let valid_timeout = match valid_lifetime with | None -> None | Some valid_lifetime -> Some (Int64.add now valid_lifetime) in - Some (ip, DEPRECATED valid_timeout), [] - | ip, DEPRECATED (Some t) when t <= now -> + Some (prefix, DEPRECATED valid_timeout), [] + | prefix, DEPRECATED (Some t) when t <= now -> + let ip = Ipaddr.Prefix.address prefix in Log.debug (fun f -> f "SLAAC: %a --> EXPIRED" Ipaddr.pp ip); None, [] - | addr -> - Some addr, [] + | x -> + Some x, [] let tick al ~now ~retrans_timer = List.fold_right (fun ip (ips, acts) -> @@ -339,22 +344,23 @@ module AddressList = struct match List.mem_assoc ip al with | false -> let al = (ip, TENTATIVE (lft, 0, Int64.add now retrans_timer)) :: al in - let dst = Ipaddr.Prefix.network_address solicited_node_prefix ip in - al, [SendNS (`Unspecified, dst, ip)] + let src = Ipaddr.Prefix.address ip in + let dst = Ipaddr.Prefix.network_address solicited_node_prefix src in + al, [SendNS (`Unspecified, dst, src)] | true -> Log.warn (fun f -> f "ndpv6: attempted to add ip %a already in address list" - Ipaddr.pp ip); + Ipaddr.Prefix.pp ip); al, [] let is_my_addr al ip = List.exists (function | _, TENTATIVE _ -> false - | ip', (PREFERRED _ | DEPRECATED _) -> Ipaddr.compare ip' ip = 0 + | ip', (PREFERRED _ | DEPRECATED _) -> Ipaddr.(compare (Prefix.address ip') ip) = 0 ) al let find_prefix al pfx = let rec loop = function - | (ip, _) :: _ when Ipaddr.Prefix.mem ip pfx -> Some ip + | (ip, _) :: _ when Ipaddr.Prefix.mem (Ipaddr.Prefix.address ip) pfx -> Some ip | _ :: rest -> loop rest | [] -> None in @@ -368,19 +374,16 @@ module AddressList = struct al, [] | None -> let ip = Ipaddr.Prefix.network_address pfx (interface_addr mac) in - add al ~now ~retrans_timer ~lft ip + let prefix = Ipaddr.Prefix.(make (bits pfx) ip) in + add al ~now ~retrans_timer ~lft prefix let handle_na al ip = (* FIXME How to notify the client? *) - try - match List.assoc ip al with - | TENTATIVE _ -> - Log.info (fun f -> f "DAD: Failed: %a" Ipaddr.pp ip); - List.remove_assoc ip al - | _ -> - al - with - | Not_found -> al + match List.partition (fun (pre, _) -> Ipaddr.Prefix.mem ip pre) al with + | [ (_, TENTATIVE _) ], rest -> + Log.info (fun f -> f "DAD: Failed: %a" Ipaddr.pp ip); + rest + | _ -> al end module PrefixList = struct @@ -1141,6 +1144,9 @@ let add_ip ~now ctx ip = process_actions ~now ctx actions let get_ip ctx = + List.map Ipaddr.Prefix.address (AddressList.to_list ctx.address_list) + +let configured_ips ctx = AddressList.to_list ctx.address_list let select_source ctx dst = diff --git a/src/ipv6/ndpv6.mli b/src/ipv6/ndpv6.mli index 4b911b5d..a353681b 100644 --- a/src/ipv6/ndpv6.mli +++ b/src/ipv6/ndpv6.mli @@ -33,7 +33,7 @@ val local : handle_ra:bool -> now:time -> random:(int -> Cstruct.t) -> Macaddr.t associated to the hardware address [mac]. [outs] is a list of ethif packets to be sent. *) -val add_ip : now:time -> context -> ipaddr -> +val add_ip : now:time -> context -> prefix -> context * (Macaddr.t * int * (Cstruct.t -> int)) list (** [add_ip ~now ctx ip] is [ctx', outs] where [ctx'] is [ctx] updated with a new local ip and [outs] is a list of ethif packets to be sent. *) @@ -41,6 +41,9 @@ val add_ip : now:time -> context -> ipaddr -> val get_ip : context -> ipaddr list (** [get_ip ctx] returns the list of local ips. *) +val configured_ips : context -> prefix list +(** [configured_ips ctx] returns the list of local prefixes. *) + val select_source : context -> ipaddr -> ipaddr (** [select_source ctx ip] returns the ip that should be put in the source field of a packet destined to [ip]. *)