Index: uspace/srv/net/inetsrv/inet_link.c
===================================================================
--- uspace/srv/net/inetsrv/inet_link.c	(revision c62a82757f97403f2ba31f76aafdf68ae74e4003)
+++ uspace/srv/net/inetsrv/inet_link.c	(revision 8d48c7e46fe4c12afd9489154fb06b10f9e2c913)
@@ -73,5 +73,5 @@
 {
 	memcpy(ip_addr, link_local_node_ip, 16);
-	
+
 	ip_addr[8] = mac_addr[0] ^ 0x02;
 	ip_addr[9] = mac_addr[1];
@@ -85,14 +85,19 @@
 {
 	log_msg(LOG_DEFAULT, LVL_DEBUG, "inet_iplink_recv()");
-	
+
 	int rc;
 	inet_packet_t packet;
-	
+	inet_link_t *ilink;
+
+	ilink = (inet_link_t *)iplink_get_userptr(iplink);
+
 	switch (ver) {
 	case ip_v4:
-		rc = inet_pdu_decode(sdu->data, sdu->size, &packet);
+		rc = inet_pdu_decode(sdu->data, sdu->size, ilink->svc_id,
+		    &packet);
 		break;
 	case ip_v6:
-		rc = inet_pdu_decode6(sdu->data, sdu->size, &packet);
+		rc = inet_pdu_decode6(sdu->data, sdu->size, ilink->svc_id,
+		    &packet);
 		break;
 	default:
@@ -100,15 +105,16 @@
 		return EINVAL;
 	}
-	
+
 	if (rc != EOK) {
 		log_msg(LOG_DEFAULT, LVL_DEBUG, "failed decoding PDU");
 		return rc;
 	}
-	
+
+	log_msg(LOG_DEFAULT, LVL_NOTE, "inet_iplink_recv: link_id=%zu", packet.link_id);
 	log_msg(LOG_DEFAULT, LVL_DEBUG, "call inet_recv_packet()");
 	rc = inet_recv_packet(&packet);
 	log_msg(LOG_DEFAULT, LVL_DEBUG, "call inet_recv_packet -> %d", rc);
 	free(packet.data);
-	
+
 	return rc;
 }
@@ -177,5 +183,5 @@
 	}
 
-	rc = iplink_open(ilink->sess, &inet_iplink_ev_ops, &ilink->iplink);
+	rc = iplink_open(ilink->sess, &inet_iplink_ev_ops, ilink, &ilink->iplink);
 	if (rc != EOK) {
 		log_msg(LOG_DEFAULT, LVL_ERROR, "Failed opening IP link '%s'",
Index: uspace/srv/net/inetsrv/inetsrv.c
===================================================================
--- uspace/srv/net/inetsrv/inetsrv.c	(revision c62a82757f97403f2ba31f76aafdf68ae74e4003)
+++ uspace/srv/net/inetsrv/inetsrv.c	(revision 8d48c7e46fe4c12afd9489154fb06b10f9e2c913)
@@ -469,8 +469,13 @@
 {
 	async_exch_t *exch = async_exchange_begin(client->sess);
-	
+
 	ipc_call_t answer;
-	aid_t req = async_send_1(exch, INET_EV_RECV, dgram->tos, &answer);
-	
+
+	log_msg(LOG_DEFAULT, LVL_NOTE, "inet_ev_recv: iplink=%zu",
+	    dgram->iplink);
+
+	aid_t req = async_send_2(exch, INET_EV_RECV, dgram->tos,
+	    dgram->iplink, &answer);
+
 	int rc = async_data_write_start(exch, &dgram->src, sizeof(inet_addr_t));
 	if (rc != EOK) {
@@ -479,5 +484,5 @@
 		return rc;
 	}
-	
+
 	rc = async_data_write_start(exch, &dgram->dest, sizeof(inet_addr_t));
 	if (rc != EOK) {
@@ -486,17 +491,17 @@
 		return rc;
 	}
-	
+
 	rc = async_data_write_start(exch, dgram->data, dgram->size);
-	
+
 	async_exchange_end(exch);
-	
+
 	if (rc != EOK) {
 		async_forget(req);
 		return rc;
 	}
-	
+
 	sysarg_t retval;
 	async_wait_for(req, &retval);
-	
+
 	return (int) retval;
 }
@@ -511,5 +516,5 @@
 	if (proto == IP_PROTO_ICMP)
 		return icmp_recv(dgram);
-	
+
 	if (proto == IP_PROTO_ICMPV6)
 		return icmpv6_recv(dgram);
@@ -540,4 +545,5 @@
 		if (packet->offs == 0 && !packet->mf) {
 			/* It is complete deliver it immediately */
+			dgram.iplink = packet->link_id;
 			dgram.src = packet->src;
 			dgram.dest = packet->dest;
Index: uspace/srv/net/inetsrv/inetsrv.h
===================================================================
--- uspace/srv/net/inetsrv/inetsrv.h	(revision c62a82757f97403f2ba31f76aafdf68ae74e4003)
+++ uspace/srv/net/inetsrv/inetsrv.h	(revision 8d48c7e46fe4c12afd9489154fb06b10f9e2c913)
@@ -75,4 +75,6 @@
 
 typedef struct {
+	/** Local link ID */
+	service_id_t link_id;
 	/** Source address */
 	inet_addr_t src;
Index: uspace/srv/net/inetsrv/pdu.c
===================================================================
--- uspace/srv/net/inetsrv/pdu.c	(revision c62a82757f97403f2ba31f76aafdf68ae74e4003)
+++ uspace/srv/net/inetsrv/pdu.c	(revision 8d48c7e46fe4c12afd9489154fb06b10f9e2c913)
@@ -298,7 +298,8 @@
 /** Decode IPv4 datagram
  *
- * @param data   Serialized IPv4 datagram
- * @param size   Length of serialized IPv4 datagram
- * @param packet IP datagram structure to be filled
+ * @param data    Serialized IPv4 datagram
+ * @param size    Length of serialized IPv4 datagram
+ * @param link_id Link on which PDU was received
+ * @param packet  IP datagram structure to be filled
  *
  * @return EOK on success
@@ -307,5 +308,6 @@
  *
  */
-int inet_pdu_decode(void *data, size_t size, inet_packet_t *packet)
+int inet_pdu_decode(void *data, size_t size, service_id_t link_id,
+    inet_packet_t *packet)
 {
 	log_msg(LOG_DEFAULT, LVL_DEBUG, "inet_pdu_decode()");
@@ -366,4 +368,5 @@
 	
 	memcpy(packet->data, (uint8_t *) data + data_offs, packet->size);
+	packet->link_id = link_id;
 	
 	return EOK;
@@ -372,7 +375,8 @@
 /** Decode IPv6 datagram
  *
- * @param data   Serialized IPv6 datagram
- * @param size   Length of serialized IPv6 datagram
- * @param packet IP datagram structure to be filled
+ * @param data    Serialized IPv6 datagram
+ * @param size    Length of serialized IPv6 datagram
+ * @param link_id Link on which PDU was received
+ * @param packet  IP datagram structure to be filled
  *
  * @return EOK on success
@@ -381,5 +385,6 @@
  *
  */
-int inet_pdu_decode6(void *data, size_t size, inet_packet_t *packet)
+int inet_pdu_decode6(void *data, size_t size, service_id_t link_id,
+    inet_packet_t *packet)
 {
 	log_msg(LOG_DEFAULT, LVL_DEBUG, "inet_pdu_decode6()");
@@ -457,5 +462,5 @@
 	
 	memcpy(packet->data, (uint8_t *) data + data_offs, packet->size);
-	
+	packet->link_id = link_id;
 	return EOK;
 }
Index: uspace/srv/net/inetsrv/pdu.h
===================================================================
--- uspace/srv/net/inetsrv/pdu.h	(revision c62a82757f97403f2ba31f76aafdf68ae74e4003)
+++ uspace/srv/net/inetsrv/pdu.h	(revision 8d48c7e46fe4c12afd9489154fb06b10f9e2c913)
@@ -38,4 +38,5 @@
 #define INET_PDU_H_
 
+#include <loc.h>
 #include <sys/types.h>
 #include "inetsrv.h"
@@ -50,6 +51,6 @@
 extern int inet_pdu_encode6(inet_packet_t *, addr128_t, addr128_t, size_t,
     size_t, void **, size_t *, size_t *);
-extern int inet_pdu_decode(void *, size_t, inet_packet_t *);
-extern int inet_pdu_decode6(void *, size_t, inet_packet_t *);
+extern int inet_pdu_decode(void *, size_t, service_id_t, inet_packet_t *);
+extern int inet_pdu_decode6(void *, size_t, service_id_t, inet_packet_t *);
 
 extern int ndp_pdu_decode(inet_dgram_t *, ndp_packet_t *);
Index: uspace/srv/net/inetsrv/reass.c
===================================================================
--- uspace/srv/net/inetsrv/reass.c	(revision c62a82757f97403f2ba31f76aafdf68ae74e4003)
+++ uspace/srv/net/inetsrv/reass.c	(revision 8d48c7e46fe4c12afd9489154fb06b10f9e2c913)
@@ -325,4 +325,6 @@
 		return ENOMEM;
 
+	/* XXX What if different fragments came from different link? */
+	dgram.iplink = frag->packet.link_id;
 	dgram.size = dgram_size;
 	dgram.src = frag->packet.src;
