switch (gb->type) {
        case GB_LOOPBACK_TYPE_PING:
        case GB_LOOPBACK_TYPE_TRANSFER:
+       case GB_LOOPBACK_TYPE_SINK:
                break;
        default:
                gb->type = 0;
 };
 ATTRIBUTE_GROUPS(loopback);
 
+static int gb_loopback_sink(struct gb_loopback *gb,
+                               struct timeval *tping, u32 len)
+{
+       struct timeval ts, te;
+       u64 elapsed_nsecs;
+       struct gb_loopback_transfer_request *request;
+       int retval;
+
+       request = kmalloc(len + sizeof(*request), GFP_KERNEL);
+       if (!request)
+               return -ENOMEM;
+
+       request->len = cpu_to_le32(len);
+
+       do_gettimeofday(&ts);
+       retval = gb_operation_sync(gb->connection, GB_LOOPBACK_TYPE_SINK,
+                                  request, len + sizeof(*request), NULL, 0);
+       do_gettimeofday(&te);
+       elapsed_nsecs = timeval_to_ns(&te) - timeval_to_ns(&ts);
+       *tping = ns_to_timeval(elapsed_nsecs);
+
+       kfree(request);
+       return retval;
+}
+
 static int gb_loopback_transfer(struct gb_loopback *gb,
                                struct timeval *tping, u32 len)
 {
                        "module-initiated version operation\n");
                return -EINVAL;
        case GB_LOOPBACK_TYPE_PING:
+       case GB_LOOPBACK_TYPE_SINK:
                return 0;
        case GB_LOOPBACK_TYPE_TRANSFER:
                if (operation->request->payload_size < sizeof(*request)) {
                        error = gb_loopback_ping(gb, &tlat);
                else if (gb->type == GB_LOOPBACK_TYPE_TRANSFER)
                        error = gb_loopback_transfer(gb, &tlat, gb->size);
+               else if (gb->type == GB_LOOPBACK_TYPE_SINK)
+                       error = gb_loopback_sink(gb, &tlat, gb->size);
                if (error)
                        gb->error++;
                if (gb->ts.tv_usec == 0 && gb->ts.tv_sec == 0) {