Index: uspace/srv/net/inetsrv/inet_link.c
===================================================================
--- uspace/srv/net/inetsrv/inet_link.c	(revision a17356fd13769fdbaa2f4df26127bb541d940247)
+++ uspace/srv/net/inetsrv/inet_link.c	(revision 3aece36bd9a285cc5208b762714a13a541498055)
@@ -49,4 +49,7 @@
 #include "pdu.h"
 
+static bool first_link = true;
+static bool first_link6 = true;
+
 static int inet_link_open(service_id_t);
 static int inet_iplink_recv(iplink_t *, iplink_recv_sdu_t *, uint16_t);
@@ -58,4 +61,20 @@
 static LIST_INITIALIZE(inet_link_list);
 static FIBRIL_MUTEX_INITIALIZE(inet_discovery_lock);
+
+static addr128_t link_local_node_ip =
+    {0xfe, 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xfe, 0, 0, 0};
+
+static void inet_link_local_node_ip(addr48_t mac_addr,
+    addr128_t ip_addr)
+{
+	memcpy(ip_addr, link_local_node_ip, 16);
+	
+	ip_addr[8] = mac_addr[0] ^ 0x02;
+	ip_addr[9] = mac_addr[1];
+	ip_addr[10] = mac_addr[2];
+	ip_addr[13] = mac_addr[3];
+	ip_addr[14] = mac_addr[4];
+	ip_addr[15] = mac_addr[5];
+}
 
 static int inet_iplink_recv(iplink_t *iplink, iplink_recv_sdu_t *sdu, uint16_t af)
@@ -159,4 +178,5 @@
 	if (ilink->svc_name != NULL)
 		free(ilink->svc_name);
+	
 	free(ilink);
 }
@@ -212,66 +232,76 @@
 	list_append(&ilink->link_list, &inet_link_list);
 
-	inet_addrobj_t *addr;
-	inet_addrobj_t *addr6;
-
-	static int first = 1;
-	
-	addr = inet_addrobj_new();
-	addr6 = inet_addrobj_new();
-	
-	if (first) {
+	inet_addrobj_t *addr = NULL;
+	
+	if (first_link) {
+		addr = inet_addrobj_new();
+		
 		inet_naddr(&addr->naddr, 127, 0, 0, 1, 24);
-		inet_naddr6(&addr6->naddr, 0, 0, 0, 0, 0, 0, 0, 1, 128);
-		first = 0;
+		first_link = false;
 	} else {
 		/*
 		 * FIXME
-		 * Setting static IP addresses for testing purposes
+		 * Setting static IPv4 address for testing purposes:
 		 * 10.0.2.15/24
-		 * fd19:1680::4/120
 		 */
+		addr = inet_addrobj_new();
+		
 		inet_naddr(&addr->naddr, 10, 0, 2, 15, 24);
-		inet_naddr6(&addr6->naddr, 0xfd19, 0x1680, 0, 0, 0, 0, 0, 4, 120);
-	}
-	
-	addr->ilink = ilink;
-	addr6->ilink = ilink;
-	addr->name = str_dup("v4a");
-	addr6->name = str_dup("v6a");
-	
-	rc = inet_addrobj_add(addr);
-	if (rc != EOK) {
-		log_msg(LOG_DEFAULT, LVL_ERROR, "Failed adding IPv4 address.");
-		inet_addrobj_delete(addr);
-		/* XXX Roll back */
-		return rc;
-	}
-	
-	rc = inet_addrobj_add(addr6);
-	if (rc != EOK) {
-		log_msg(LOG_DEFAULT, LVL_ERROR, "Failed adding IPv6 address.");
-		inet_addrobj_delete(addr6);
-		/* XXX Roll back */
-		return rc;
-	}
-	
-	inet_naddr_addr(&addr->naddr, &iaddr);
-	rc = iplink_addr_add(ilink->iplink, &iaddr);
-	if (rc != EOK) {
-		log_msg(LOG_DEFAULT, LVL_ERROR, "Failed setting IPv4 address on internet link.");
-		inet_addrobj_remove(addr);
-		inet_addrobj_delete(addr);
-		/* XXX Roll back */
-		return rc;
-	}
-	
-	inet_naddr_addr(&addr6->naddr, &iaddr);
-	rc = iplink_addr_add(ilink->iplink, &iaddr);
-	if (rc != EOK) {
-		log_msg(LOG_DEFAULT, LVL_ERROR, "Failed setting IPv6 address on internet link.");
-		inet_addrobj_remove(addr6);
-		inet_addrobj_delete(addr6);
-		/* XXX Roll back */
-		return rc;
+	}
+	
+	if (addr != NULL) {
+		addr->ilink = ilink;
+		addr->name = str_dup("v4a");
+		
+		rc = inet_addrobj_add(addr);
+		if (rc == EOK) {
+			inet_naddr_addr(&addr->naddr, &iaddr);
+			rc = iplink_addr_add(ilink->iplink, &iaddr);
+			if (rc != EOK) {
+				log_msg(LOG_DEFAULT, LVL_ERROR,
+				    "Failed setting IPv4 address on internet link.");
+				inet_addrobj_remove(addr);
+				inet_addrobj_delete(addr);
+			}
+		} else {
+			log_msg(LOG_DEFAULT, LVL_ERROR, "Failed adding IPv4 address.");
+			inet_addrobj_delete(addr);
+		}
+	}
+	
+	inet_addrobj_t *addr6 = NULL;
+	
+	if (first_link6) {
+		addr6 = inet_addrobj_new();
+		
+		inet_naddr6(&addr6->naddr, 0, 0, 0, 0, 0, 0, 0, 1, 128);
+		first_link6 = false;
+	} else if (ilink->mac_valid) {
+		addr6 = inet_addrobj_new();
+		
+		addr128_t link_local;
+		inet_link_local_node_ip(ilink->mac, link_local);
+		
+		inet_naddr_set6(link_local, 64, &addr6->naddr);
+	}
+	
+	if (addr6 != NULL) {
+		addr6->ilink = ilink;
+		addr6->name = str_dup("v6a");
+		
+		rc = inet_addrobj_add(addr6);
+		if (rc == EOK) {
+			inet_naddr_addr(&addr6->naddr, &iaddr);
+			rc = iplink_addr_add(ilink->iplink, &iaddr);
+			if (rc != EOK) {
+				log_msg(LOG_DEFAULT, LVL_ERROR,
+				    "Failed setting IPv6 address on internet link.");
+				inet_addrobj_remove(addr6);
+				inet_addrobj_delete(addr6);
+			}
+		} else {
+			log_msg(LOG_DEFAULT, LVL_ERROR, "Failed adding IPv6 address.");
+			inet_addrobj_delete(addr6);
+		}
 	}
 	
