Skip to content

Commit c53383c

Browse files
author
Jon Ludlam
committed
Merge pull request #15 from jonludlam/CA-82314
CA-82314
2 parents 3e552d3 + 15b602b commit c53383c

File tree

3 files changed

+55
-6
lines changed

3 files changed

+55
-6
lines changed

lib/network_utils.ml

Lines changed: 44 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,42 @@ info "Found at [ %s ]" (String.concat ", " (List.map string_of_int indices));
234234
Some (ip, prefixlen)
235235
with Not_found -> None
236236

237+
(* see http://en.wikipedia.org/wiki/IPv6_address#Modified_EUI-64 *)
238+
let get_ipv6_interface_id dev =
239+
let mac = get_mac dev in
240+
let bytes = List.map (fun byte -> int_of_string ("0x" ^ byte)) (String.split ':' mac) in
241+
let rec modified_bytes ac i = function
242+
| [] ->
243+
ac
244+
| head :: tail ->
245+
if i = 0 then
246+
let head' = head lxor 2 in
247+
modified_bytes (head' :: ac) 1 tail
248+
else if i = 2 then
249+
modified_bytes (254 :: 255 :: head :: ac) 3 tail
250+
else
251+
modified_bytes (head :: ac) (i + 1) tail
252+
in
253+
let bytes' = List.rev (modified_bytes [] 0 bytes) in
254+
[0; 0; 0; 0; 0; 0; 0; 0] @ bytes'
255+
256+
let get_ipv6_link_local_addr dev =
257+
let id = get_ipv6_interface_id dev in
258+
let link_local = 0xfe :: 0x80 :: (List.tl (List.tl id)) in
259+
let rec to_string ac i = function
260+
| [] -> ac
261+
| hd :: tl ->
262+
let separator =
263+
if i = 0 || i mod 2 = 1 then
264+
""
265+
else
266+
":"
267+
in
268+
let ac' = ac ^ separator ^ Printf.sprintf "%02x" hd in
269+
to_string ac' (i + 1) tl
270+
in
271+
to_string "" 0 link_local ^ "/64"
272+
237273
let get_ipv4 dev =
238274
let addrs = addr dev "inet" in
239275
List.filter_map split_addr addrs
@@ -254,13 +290,16 @@ info "Found at [ %s ]" (String.concat ", " (List.map string_of_int indices));
254290
ignore (call ~log:true (["addr"; "add"; addr; "dev"; dev] @ broadcast))
255291
with _ -> ()
256292

293+
let set_ipv6_link_local_addr dev =
294+
let addr = get_ipv6_link_local_addr dev in
295+
try
296+
ignore (call ~log:true ["addr"; "add"; addr; "dev"; dev; "scope"; "link"])
297+
with _ -> ()
298+
257299
let flush_ip_addr ?(ipv6=false) dev =
258300
try
259-
if ipv6 then begin
260-
ignore (call ~log:true ["-6"; "addr"; "flush"; "dev"; dev; "scope"; "global"]);
261-
ignore (call ~log:true ["-6"; "addr"; "flush"; "dev"; dev; "scope"; "site"])
262-
end else
263-
ignore (call ~log:true ["-4"; "addr"; "flush"; "dev"; dev])
301+
let mode = if ipv6 then "-6" else "-4" in
302+
ignore (call ~log:true [mode; "addr"; "flush"; "dev"; dev])
264303
with _ -> ()
265304

266305
let route_show ?(version=V46) dev =

networkd/network_server.ml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,20 +194,30 @@ module Interface = struct
194194
Sysctl.set_ipv6_autoconf name false;
195195
Ip.flush_ip_addr ~ipv6:true name
196196
end
197+
| Linklocal6 ->
198+
if List.mem name (Sysfs.list ()) then begin
199+
Dhcp6c.stop name;
200+
Sysctl.set_ipv6_autoconf name false;
201+
Ip.flush_ip_addr ~ipv6:true name;
202+
Ip.set_ipv6_link_local_addr name
203+
end
197204
| DHCP6 ->
198205
Dhcp6c.stop name;
199206
Sysctl.set_ipv6_autoconf name false;
200207
Ip.flush_ip_addr ~ipv6:true name;
208+
Ip.set_ipv6_link_local_addr name;
201209
Dhcp6c.start name
202210
| Autoconf6 ->
203211
Dhcp6c.stop name;
204212
Ip.flush_ip_addr ~ipv6:true name;
213+
Ip.set_ipv6_link_local_addr name;
205214
Sysctl.set_ipv6_autoconf name true;
206215
(* Cannot link set down/up due to CA-89882 - IPv4 default route cleared *)
207216
| Static6 addrs ->
208217
Dhcp6c.stop name;
209218
Sysctl.set_ipv6_autoconf name false;
210219
Ip.flush_ip_addr ~ipv6:true name;
220+
Ip.set_ipv6_link_local_addr name;
211221
List.iter (Ip.set_ip_addr name) addrs
212222
) ()
213223

networkd_db/networkd_db.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ let _ =
8888
| Some addr -> ["gatewayv6", Unix.string_of_inet_addr addr]
8989
in
9090
mode @ addrs @ gateway
91-
| None6 -> []
91+
| None6 | Linklocal6 -> []
9292
in
9393
let data = datav4 @ datav6 in
9494
List.iter (fun (k, v) -> Printf.printf "%s=%s\n" k v) data

0 commit comments

Comments
 (0)