diff --git a/Makefile.dep b/Makefile.dep
index 2eb99d5a6996611080d66c6f890a32a81356539b..143d9c6caf7efcf39451356d7acb1150cdf63a38 100644
--- a/Makefile.dep
+++ b/Makefile.dep
@@ -180,6 +180,10 @@ ifneq (,$(filter ng_pktdump,$(USEMODULE)))
   USEMODULE += od
 endif
 
+ifneq (,$(filter ng_slip,$(USEMODULE)))
+  USEMODULE += ng_netbase
+endif
+
 ifneq (,$(filter aodvv2,$(USEMODULE)))
   USEMODULE += vtimer
   USEMODULE += sixlowpan
diff --git a/sys/Makefile b/sys/Makefile
index 567fca59a130943e3b3037b22417240b63aa1f58..71fdea57aee6b6a025cecb862e65592a4a3a80d8 100644
--- a/sys/Makefile
+++ b/sys/Makefile
@@ -119,6 +119,9 @@ endif
 ifneq (,$(filter ng_sixlowpan_netif,$(USEMODULE)))
     DIRS += net/network_layer/ng_sixlowpan/netif
 endif
+ifneq (,$(filter ng_slip,$(USEMODULE)))
+    DIRS += net/link_layer/ng_slip
+endif
 ifneq (,$(filter netapi,$(USEMODULE)))
     DIRS += net/crosslayer/netapi
 endif
diff --git a/sys/Makefile.include b/sys/Makefile.include
index 0eb54fa292d0773b024e1837ee0d7965b43ac2dc..c491b9851fb7c9e3ae19ae8253fcad6426c99d90 100644
--- a/sys/Makefile.include
+++ b/sys/Makefile.include
@@ -82,6 +82,10 @@ ifneq (,$(filter cpp11-compat,$(USEMODULE)))
     USEMODULE_INCLUDES += $(RIOTBASE)/sys/cpp11-compat/include
 endif
 
+ifneq (,$(filter ng_slip,$(USEMODULE)))
+    FEATURES_REQUIRED += periph_uart
+endif
+
 ifneq (,$(filter embunit,$(USEMODULE)))
     ifeq ($(OUTPUT),XML)
         CFLAGS += -DOUTPUT=OUTPUT_XML
diff --git a/sys/include/net/ng_slip.h b/sys/include/net/ng_slip.h
new file mode 100644
index 0000000000000000000000000000000000000000..b3c5cb82a84e633214fde22f1fdda7766e28d648
--- /dev/null
+++ b/sys/include/net/ng_slip.h
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2015 Martine Lenders <mlenders@inf.fu-berlin.de>
+ *
+ * This file is subject to the terms and conditions of the GNU Lesser
+ * General Public License v2.1. See the file LICENSE in the top level
+ * directory for more details.
+ */
+
+/**
+ * @defgroup    net_ng_slip SLIP
+ * @ingroup     net
+ * @brief       Provides a SLIP interface over UART utilizing
+ *              @ref driver_periph_uart.
+ * @see         <a href="https://www.ietf.org/rfc/rfc1055">RFC 1055</a>
+ * @{
+ *
+ * @file
+ * @brief       SLIP interface defintion
+ *
+ * @author      Martine Lenders <mlenders@inf.fu-berlin.de>
+ * @author      Hauke Petersen <hauke.petersen@fu-berlin.de>
+ */
+
+#ifndef NG_SLIP_H_
+#define NG_SLIP_H_
+
+#include <inttypes.h>
+
+#include "net/ng_netbase.h"
+#include "periph/uart.h"
+#include "ringbuffer.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief   UART buffer size used for TX and RX buffers
+ *
+ * Reduce this value if your expected traffic does not include full IPv6 MTU
+ * sized packets
+ */
+#ifndef NG_SLIP_BUFSIZE
+#define NG_SLIP_BUFSIZE         (1500U)
+#endif
+
+/**
+ * @brief   Device descriptor for SLIP devices
+ */
+typedef struct {
+    uart_t uart;                    /**< the UART interface */
+    ringbuffer_t *in_buf;           /**< RX buffer */
+    ringbuffer_t *out_buf;          /**< TX buffer */
+    char rx_mem[NG_SLIP_BUFSIZE];   /**< memory used by RX buffer */
+    char tx_mem[NG_SLIP_BUFSIZE];   /**< memory used by TX buffer */
+    uint32_t in_bytes;              /**< the number of bytes received of a
+                                     *   currently incoming packet */
+    uint16_t in_esc;                /**< receiver is in escape mode */
+    kernel_pid_t slip_pid;          /**< PID of the device thread */
+} ng_slip_dev_t;
+
+/**
+ * @brief   Initializes a new @ref net_ng_slip control thread for UART device
+ *          @p uart
+ *
+ * @param[in] dev           un-initialized SLIP device descriptor
+ * @param[in] uart          UART device to use
+ * @param[in] baudrate      baudrate to use
+ * @param[in] stack         stack memory to use for the SLIP devices thread
+ * @param[in] stack_size    size of @p stack
+ * @param[in] priority      priority for the newly created thread
+ *
+ * @return  PID of SLIP thread on success
+ * @return  -EFAULT, if slip thread could not be created
+ * @return  -ENODEV, if ng_slip_dev_t::uart of @p dev was no valid UART
+ */
+kernel_pid_t ng_slip_init(ng_slip_dev_t *dev, uart_t uart, uint32_t baudrate,
+                          char *stack, size_t stack_size, char priority);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __SLIP_H_ */
+/** @} */
diff --git a/sys/net/link_layer/ng_slip/Makefile b/sys/net/link_layer/ng_slip/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..48422e909a47d7cd428d10fa73825060ccc8d8c2
--- /dev/null
+++ b/sys/net/link_layer/ng_slip/Makefile
@@ -0,0 +1 @@
+include $(RIOTBASE)/Makefile.base
diff --git a/sys/net/link_layer/ng_slip/ng_slip.c b/sys/net/link_layer/ng_slip/ng_slip.c
new file mode 100644
index 0000000000000000000000000000000000000000..61f95ef0be1d4d2842cf3d8dd5b5131227716e40
--- /dev/null
+++ b/sys/net/link_layer/ng_slip/ng_slip.c
@@ -0,0 +1,284 @@
+/*
+ * Copyright (C) 2015 Martine Lenders <mlenders@inf.fu-berlin.de>
+ *
+ * This file is subject to the terms and conditions of the GNU Lesser
+ * General Public License v2.1. See the file LICENSE in the top level
+ * directory for more details.
+ */
+
+/**
+ * @ingroup     net_ng_slip
+ * @{
+ *
+ * @file
+ * @brief       SLIP device implementation
+ *
+ * @author      Martine Lenders <mlenders@inf.fu-berlin.de>
+ * @author      Hauke Petersen <hauke.petersen@fu-berlin.de>
+ *
+ * @}
+ */
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "kernel.h"
+#include "kernel_types.h"
+#include "msg.h"
+#include "net/ng_netbase.h"
+#include "periph/uart.h"
+#include "ringbuffer.h"
+#include "thread.h"
+#include "net/ng_ipv6/hdr.h"
+
+#include "net/ng_slip.h"
+
+#define ENABLE_DEBUG    (0)
+#include "debug.h"
+
+#define _SLIP_END               ('\xc0')
+#define _SLIP_ESC               ('\xdb')
+#define _SLIP_END_ESC           ('\xdc')
+#define _SLIP_ESC_ESC           ('\xdd')
+
+#define _SLIP_MSG_TYPE          (0xc1dc)    /* chosen randomly */
+#define _SLIP_NAME              "SLIP"
+#define _SLIP_MSG_QUEUE_SIZE    (8U)
+
+#define _SLIP_DEV(arg)    ((ng_slip_dev_t *)arg)
+
+/* UART callbacks */
+static void _slip_rx_cb(void *arg, char data)
+{
+    if (data == _SLIP_END) {
+        msg_t msg;
+
+        msg.type = _SLIP_MSG_TYPE;
+        msg.content.value = _SLIP_DEV(arg)->in_bytes;
+
+        msg_send_int(&msg, _SLIP_DEV(arg)->slip_pid);
+
+        _SLIP_DEV(arg)->in_bytes = 0;
+    }
+
+    if (_SLIP_DEV(arg)->in_esc) {
+        _SLIP_DEV(arg)->in_esc = 0;
+
+        switch (data) {
+            case (_SLIP_END_ESC):
+                if (ringbuffer_add_one(_SLIP_DEV(arg)->in_buf, _SLIP_END) < 0) {
+                    _SLIP_DEV(arg)->in_bytes++;
+                }
+
+                break;
+
+            case (_SLIP_ESC_ESC):
+                if (ringbuffer_add_one(_SLIP_DEV(arg)->in_buf, _SLIP_ESC) < 0) {
+                    _SLIP_DEV(arg)->in_bytes++;
+                }
+
+                break;
+
+            default:
+                break;
+        }
+    }
+    else if (data == _SLIP_ESC) {
+        _SLIP_DEV(arg)->in_esc = 1;
+    }
+    else {
+        if (ringbuffer_add_one(_SLIP_DEV(arg)->in_buf, data) < 0) {
+            _SLIP_DEV(arg)->in_bytes++;
+        }
+    }
+}
+
+int _slip_tx_cb(void *arg)
+{
+    if (_SLIP_DEV(arg)->out_buf->avail > 0) {
+        char c = (char)ringbuffer_get_one(_SLIP_DEV(arg)->out_buf);
+        uart_write((uart_t)(_SLIP_DEV(arg)->uart), c);
+        return 1;
+    }
+
+    return 0;
+}
+
+/* SLIP receive handler */
+static void _slip_receive(ng_slip_dev_t *dev, size_t bytes)
+{
+    ng_netif_hdr_t *hdr;
+    ng_netreg_entry_t *sendto;
+    ng_pktsnip_t *pkt, *netif_hdr;
+
+    pkt = ng_pktbuf_add(NULL, NULL, bytes, NG_NETTYPE_UNDEF);
+
+    if (pkt == NULL) {
+        DEBUG("slip: no space left in packet buffer\n");
+        return;
+    }
+
+    netif_hdr = ng_pktbuf_add(pkt, NULL, sizeof(ng_netif_hdr_t),
+                              NG_NETTYPE_NETIF);
+
+    if (netif_hdr == NULL) {
+        DEBUG("slip: no space left in packet buffer\n");
+        ng_pktbuf_release(pkt);
+        return;
+    }
+
+    hdr = netif_hdr->data;
+    ng_netif_hdr_init(hdr, 0, 0);
+    hdr->if_pid = thread_getpid();
+
+    if (ringbuffer_get(dev->in_buf, pkt->data, bytes) != bytes) {
+        DEBUG("slip: could not read %zu bytes from ringbuffer\n", bytes);
+        ng_pktbuf_release(pkt);
+        return;
+    }
+
+#ifdef MODULE_NG_IPV6
+    if ((pkt->size >= sizeof(ng_ipv6_hdr_t)) && ng_ipv6_hdr_is_ipv6_hdr(pkt->data)) {
+        pkt->type = NG_NETTYPE_IPV6;
+    }
+#endif
+
+    sendto = ng_netreg_lookup(pkt->type, NG_NETREG_DEMUX_CTX_ALL);
+
+    if (sendto == NULL) {
+        DEBUG("slip: unable to forward packet of type %i\n", pkt->type);
+        ng_pktbuf_release(pkt);
+    }
+
+    ng_pktbuf_hold(pkt, ng_netreg_num(pkt->type, NG_NETREG_DEMUX_CTX_ALL) - 1);
+
+    while (sendto != NULL) {
+        DEBUG("slip: sending pkt %p to PID %u\n", pkt, sendto->pid);
+        ng_netapi_receive(sendto->pid, pkt);
+        sendto = ng_netreg_getnext(sendto);
+    }
+}
+
+static inline void _slip_send_char(ng_slip_dev_t *dev, char c)
+{
+    ringbuffer_add_one(dev->out_buf, c);
+    uart_tx_begin(dev->uart);
+}
+
+/* SLIP send handler */
+static void _slip_send(ng_slip_dev_t *dev, ng_pktsnip_t *pkt)
+{
+    ng_pktsnip_t *ptr;
+
+    ptr = pkt->next;    /* ignore ng_netif_hdr_t, we don't need it */
+
+    while (ptr != NULL) {
+        DEBUG("slip: send pktsnip of length %zu over UART_%d\n", ptr->size, uart);
+        char *data = ptr->data;
+
+        for (size_t i = 0; i < ptr->size; i++) {
+            switch (data[i]) {
+                case _SLIP_END:
+                    DEBUG("slip: encountered END byte on send: stuff with ESC\n");
+                    _slip_send_char(dev, _SLIP_ESC);
+                    _slip_send_char(dev, _SLIP_END_ESC);
+                    break;
+
+                case _SLIP_ESC:
+                    DEBUG("slip: encountered ESC byte on send: stuff with ESC\n");
+                    _slip_send_char(dev, _SLIP_ESC);
+                    _slip_send_char(dev, _SLIP_ESC_ESC);
+                    break;
+
+                default:
+                    _slip_send_char(dev, data[i]);
+
+                    break;
+            }
+        }
+
+        ptr = ptr->next;
+    }
+
+    _slip_send_char(dev, _SLIP_END);
+
+    ng_pktbuf_release(pkt);
+}
+
+static void *_slip(void *args)
+{
+    ng_slip_dev_t *dev = _SLIP_DEV(args);
+    msg_t msg, reply, msg_q[_SLIP_MSG_QUEUE_SIZE];
+
+    msg_init_queue(msg_q, _SLIP_MSG_QUEUE_SIZE);
+    dev->slip_pid = thread_getpid();
+    ng_netif_add(dev->slip_pid);
+
+    DEBUG("slip: SLIP runs on UART_%d\n", uart);
+
+    while (1) {
+        DEBUG("slip: waiting for incoming messages\n");
+        msg_receive(&msg);
+
+        switch (msg.type) {
+            case _SLIP_MSG_TYPE:
+                DEBUG("slip: incoming message from UART in buffer\n");
+                _slip_receive(dev, (size_t)msg.content.value);
+                break;
+
+            case NG_NETAPI_MSG_TYPE_SND:
+                DEBUG("slip: NG_NETAPI_MSG_TYPE_SND received\n");
+                _slip_send(dev, (ng_pktsnip_t *)msg.content.ptr);
+                break;
+
+            case NG_NETAPI_MSG_TYPE_GET:
+            case NG_NETAPI_MSG_TYPE_SET:
+                DEBUG("slip: NG_NETAPI_MSG_TYPE_GET or NG_NETAPI_MSG_TYPE_SET received\n");
+                reply.type = NG_NETAPI_MSG_TYPE_ACK;
+                reply.content.value = (uint32_t)(-ENOTSUP);
+                DEBUG("slip: I don't support these but have to reply.\n");
+                msg_reply(&msg, &reply);
+                break;
+        }
+    }
+
+    /* should be never reached */
+    return NULL;
+}
+
+kernel_pid_t ng_slip_init(ng_slip_dev_t *dev, uart_t uart, uint32_t baudrate,
+                          char *stack, size_t stack_size, char priority)
+{
+    int res;
+    kernel_pid_t pid;
+
+    /* reset device descriptor fields */
+    dev->in_bytes = 0;
+    dev->in_esc = 0;
+    dev->slip_pid = KERNEL_PID_UNDEF;
+
+    /* initialize buffers */
+    ringbuffer_init(dev->in_buf, dev->rx_mem, sizeof(dev->rx_mem));
+    ringbuffer_init(dev->out_buf, dev->tx_mem, sizeof(dev->tx_mem));
+
+    /* initialize UART */
+    DEBUG("slip: initialize UART_%d\n", uart);
+    res = uart_init(uart, baudrate, _slip_rx_cb, _slip_tx_cb, dev);
+    if (res < 0) {
+        DEBUG("slip: error initializing UART_%i with baudrate %u\n",
+              uart, baudrate);
+        return -ENODEV;
+    }
+
+    /* start SLIP thread */
+    DEBUG("slip: starting SLIP thread\n");
+    pid = thread_create(stack, stack_size, priority, CREATE_STACKTEST,
+                        _slip, dev, _SLIP_NAME);
+    if (pid < 0) {
+        DEBUG("slip: unable to create SLIP thread\n");
+        return -EFAULT;
+    }
+    return res;
+}