Skip to content

Commit

Permalink
Merge pull request xapi-project#15 from jonludlam/CA-82314
Browse files Browse the repository at this point in the history
CA-82314
  • Loading branch information
Jon Ludlam committed Aug 23, 2013
2 parents 3e552d3 + 15b602b commit c53383c
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 6 deletions.
49 changes: 44 additions & 5 deletions lib/network_utils.ml
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,42 @@ info "Found at [ %s ]" (String.concat ", " (List.map string_of_int indices));
Some (ip, prefixlen)
with Not_found -> None

(* see http://en.wikipedia.org/wiki/IPv6_address#Modified_EUI-64 *)
let get_ipv6_interface_id dev =
let mac = get_mac dev in
let bytes = List.map (fun byte -> int_of_string ("0x" ^ byte)) (String.split ':' mac) in
let rec modified_bytes ac i = function
| [] ->
ac
| head :: tail ->
if i = 0 then
let head' = head lxor 2 in
modified_bytes (head' :: ac) 1 tail
else if i = 2 then
modified_bytes (254 :: 255 :: head :: ac) 3 tail
else
modified_bytes (head :: ac) (i + 1) tail
in
let bytes' = List.rev (modified_bytes [] 0 bytes) in
[0; 0; 0; 0; 0; 0; 0; 0] @ bytes'

let get_ipv6_link_local_addr dev =
let id = get_ipv6_interface_id dev in
let link_local = 0xfe :: 0x80 :: (List.tl (List.tl id)) in
let rec to_string ac i = function
| [] -> ac
| hd :: tl ->
let separator =
if i = 0 || i mod 2 = 1 then
""
else
":"
in
let ac' = ac ^ separator ^ Printf.sprintf "%02x" hd in
to_string ac' (i + 1) tl
in
to_string "" 0 link_local ^ "/64"

let get_ipv4 dev =
let addrs = addr dev "inet" in
List.filter_map split_addr addrs
Expand All @@ -254,13 +290,16 @@ info "Found at [ %s ]" (String.concat ", " (List.map string_of_int indices));
ignore (call ~log:true (["addr"; "add"; addr; "dev"; dev] @ broadcast))
with _ -> ()

let set_ipv6_link_local_addr dev =
let addr = get_ipv6_link_local_addr dev in
try
ignore (call ~log:true ["addr"; "add"; addr; "dev"; dev; "scope"; "link"])
with _ -> ()

let flush_ip_addr ?(ipv6=false) dev =
try
if ipv6 then begin
ignore (call ~log:true ["-6"; "addr"; "flush"; "dev"; dev; "scope"; "global"]);
ignore (call ~log:true ["-6"; "addr"; "flush"; "dev"; dev; "scope"; "site"])
end else
ignore (call ~log:true ["-4"; "addr"; "flush"; "dev"; dev])
let mode = if ipv6 then "-6" else "-4" in
ignore (call ~log:true [mode; "addr"; "flush"; "dev"; dev])
with _ -> ()

let route_show ?(version=V46) dev =
Expand Down
10 changes: 10 additions & 0 deletions networkd/network_server.ml
Original file line number Diff line number Diff line change
Expand Up @@ -194,20 +194,30 @@ module Interface = struct
Sysctl.set_ipv6_autoconf name false;
Ip.flush_ip_addr ~ipv6:true name
end
| Linklocal6 ->
if List.mem name (Sysfs.list ()) then begin
Dhcp6c.stop name;
Sysctl.set_ipv6_autoconf name false;
Ip.flush_ip_addr ~ipv6:true name;
Ip.set_ipv6_link_local_addr name
end
| DHCP6 ->
Dhcp6c.stop name;
Sysctl.set_ipv6_autoconf name false;
Ip.flush_ip_addr ~ipv6:true name;
Ip.set_ipv6_link_local_addr name;
Dhcp6c.start name
| Autoconf6 ->
Dhcp6c.stop name;
Ip.flush_ip_addr ~ipv6:true name;
Ip.set_ipv6_link_local_addr name;
Sysctl.set_ipv6_autoconf name true;
(* Cannot link set down/up due to CA-89882 - IPv4 default route cleared *)
| Static6 addrs ->
Dhcp6c.stop name;
Sysctl.set_ipv6_autoconf name false;
Ip.flush_ip_addr ~ipv6:true name;
Ip.set_ipv6_link_local_addr name;
List.iter (Ip.set_ip_addr name) addrs
) ()

Expand Down
2 changes: 1 addition & 1 deletion networkd_db/networkd_db.ml
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ let _ =
| Some addr -> ["gatewayv6", Unix.string_of_inet_addr addr]
in
mode @ addrs @ gateway
| None6 -> []
| None6 | Linklocal6 -> []
in
let data = datav4 @ datav6 in
List.iter (fun (k, v) -> Printf.printf "%s=%s\n" k v) data
Expand Down

0 comments on commit c53383c

Please sign in to comment.