diff --git a/sys/include/net/gnrc/tcp.h b/sys/include/net/gnrc/tcp.h
index 773a0f48fdebe33aa3feabacf3a0d211b55e2baa..67da62adedbcd20b68985b3eb3e352a2364f23c0 100644
--- a/sys/include/net/gnrc/tcp.h
+++ b/sys/include/net/gnrc/tcp.h
@@ -174,10 +174,18 @@ ssize_t gnrc_tcp_recv(gnrc_tcp_tcb_t *tcb, void *data, const size_t max_len,
  * @pre @p tcb must not be NULL.
  *
  * @param[in,out] tcb   TCB holding the connection information.
+ */
+void gnrc_tcp_close(gnrc_tcp_tcb_t *tcb);
+
+/**
+ * @brief Abort a TCP connection.
  *
- * @returns   Zero on success.
+ * @pre gnrc_tcp_tcb_init() must have been successfully called.
+ * @pre @p tcb must not be NULL.
+ *
+ * @param[in,out] tcb   TCB holding the connection information.
  */
-int gnrc_tcp_close(gnrc_tcp_tcb_t *tcb);
+void gnrc_tcp_abort(gnrc_tcp_tcb_t *tcb);
 
 /**
  * @brief Calculate and set checksum in TCP header.
diff --git a/sys/net/gnrc/transport_layer/tcp/gnrc_tcp.c b/sys/net/gnrc/transport_layer/tcp/gnrc_tcp.c
index e9ac63efc2c1e1fe4fffb08f0d6c3fd1d3ba6d87..eff2585686e27b382dba763a5fd80b874637a9a3 100644
--- a/sys/net/gnrc/transport_layer/tcp/gnrc_tcp.c
+++ b/sys/net/gnrc/transport_layer/tcp/gnrc_tcp.c
@@ -473,7 +473,7 @@ ssize_t gnrc_tcp_recv(gnrc_tcp_tcb_t *tcb, void *data, const size_t max_len,
     return ret;
 }
 
-int gnrc_tcp_close(gnrc_tcp_tcb_t *tcb)
+void gnrc_tcp_close(gnrc_tcp_tcb_t *tcb)
 {
     assert(tcb != NULL);
 
@@ -521,7 +521,19 @@ int gnrc_tcp_close(gnrc_tcp_tcb_t *tcb)
     xtimer_remove(&connection_timeout_timer);
     tcb->owner = KERNEL_PID_UNDEF;
     mutex_unlock(&(tcb->function_lock));
-    return 0;
+}
+
+void gnrc_tcp_abort(gnrc_tcp_tcb_t *tcb)
+{
+    assert(tcb != NULL);
+
+    /* Lock the TCB for this function call */
+    mutex_lock(&(tcb->function_lock));
+    if (tcb->state != FSM_STATE_CLOSED) {
+        /* Call FSM ABORT event */
+        _fsm(tcb, FSM_EVENT_CALL_ABORT, NULL, NULL, 0);
+    }
+    mutex_unlock(&(tcb->function_lock));
 }
 
 int gnrc_tcp_calc_csum(const gnrc_pktsnip_t *hdr, const gnrc_pktsnip_t *pseudo_hdr)
diff --git a/sys/net/gnrc/transport_layer/tcp/gnrc_tcp_fsm.c b/sys/net/gnrc/transport_layer/tcp/gnrc_tcp_fsm.c
index 67daf7e391b2d95037e074ac57717da4acd0bca0..a89fd3b842881ea97e744b719a50d092ec213294 100644
--- a/sys/net/gnrc/transport_layer/tcp/gnrc_tcp_fsm.c
+++ b/sys/net/gnrc/transport_layer/tcp/gnrc_tcp_fsm.c
@@ -215,9 +215,7 @@ static int _transition_to(gnrc_tcp_tcb_t *tcb, fsm_state_t state)
  */
 static int _fsm_call_open(gnrc_tcp_tcb_t *tcb)
 {
-    gnrc_pktsnip_t *out_pkt = NULL;     /* Outgoing packet */
-    uint16_t seq_con = 0;               /* Sequence number consumption of outgoing packet */
-    int ret = 0;                        /* Return value */
+    int ret = 0;
 
     DEBUG("gnrc_tcp_fsm.c : _fsm_call_open()\n");
     tcb->rcv_wnd = GNRC_TCP_DEFAULT_WINDOW;
@@ -243,6 +241,8 @@ static int _fsm_call_open(gnrc_tcp_tcb_t *tcb)
         }
 
         /* Send SYN */
+        gnrc_pktsnip_t *out_pkt = NULL;
+        uint16_t seq_con = 0;
         _pkt_build(tcb, &out_pkt, &seq_con, MSK_SYN, tcb->iss, 0, NULL, 0);
         _pkt_setup_retransmit(tcb, out_pkt, false);
         _pkt_send(tcb, out_pkt, seq_con, false);
@@ -261,10 +261,8 @@ static int _fsm_call_open(gnrc_tcp_tcb_t *tcb)
  */
 static int _fsm_call_send(gnrc_tcp_tcb_t *tcb, void *buf, size_t len)
 {
-    gnrc_pktsnip_t *out_pkt = NULL;     /* Outgoing packet */
-    uint16_t seq_con = 0;               /* Sequence number consumption (out_pkt) */
-
     DEBUG("gnrc_tcp_fsm.c : _fsm_call_send()\n");
+
     size_t payload = (tcb->snd_una + tcb->snd_wnd) - tcb->snd_nxt;
 
     /* Check if window is open and all packets were transmitted */
@@ -275,6 +273,8 @@ static int _fsm_call_send(gnrc_tcp_tcb_t *tcb, void *buf, size_t len)
         payload = (payload < len) ? payload : len;
 
         /* Calculate payload size for this segment */
+        gnrc_pktsnip_t *out_pkt = NULL;
+        uint16_t seq_con = 0;
         _pkt_build(tcb, &out_pkt, &seq_con, MSK_ACK, tcb->snd_nxt, tcb->rcv_nxt, buf, payload);
         _pkt_setup_retransmit(tcb, out_pkt, false);
         _pkt_send(tcb, out_pkt, seq_con, false);
@@ -294,10 +294,8 @@ static int _fsm_call_send(gnrc_tcp_tcb_t *tcb, void *buf, size_t len)
  */
 static int _fsm_call_recv(gnrc_tcp_tcb_t *tcb, void *buf, size_t len)
 {
-    gnrc_pktsnip_t *out_pkt = NULL;     /* Outgoing packet */
-    uint16_t seq_con = 0;               /* Sequence number consumption of outgoing packet */
-
     DEBUG("gnrc_tcp_fsm.c : _fsm_call_recv()\n");
+
     if (ringbuffer_empty(&tcb->rcv_buf)) {
         return 0;
     }
@@ -310,6 +308,8 @@ static int _fsm_call_recv(gnrc_tcp_tcb_t *tcb, void *buf, size_t len)
         tcb->rcv_wnd = ringbuffer_get_free(&(tcb->rcv_buf));
 
         /* Send ACK to anounce window update */
+        gnrc_pktsnip_t *out_pkt = NULL;
+        uint16_t seq_con = 0;
         _pkt_build(tcb, &out_pkt, &seq_con, MSK_ACK, tcb->snd_nxt, tcb->rcv_nxt, NULL, 0);
         _pkt_send(tcb, out_pkt, seq_con, false);
     }
@@ -325,13 +325,14 @@ static int _fsm_call_recv(gnrc_tcp_tcb_t *tcb, void *buf, size_t len)
  */
 static int _fsm_call_close(gnrc_tcp_tcb_t *tcb)
 {
-    gnrc_pktsnip_t *out_pkt = NULL;     /* Outgoing packet */
-    uint16_t seq_con = 0;               /* Sequence number consumption of outgoing packet */
-
     DEBUG("gnrc_tcp_fsm.c : _fsm_call_close()\n");
+
     if (tcb->state == FSM_STATE_SYN_RCVD || tcb->state == FSM_STATE_ESTABLISHED ||
         tcb->state == FSM_STATE_CLOSE_WAIT) {
+
         /* Send FIN packet */
+        gnrc_pktsnip_t *out_pkt = NULL;
+        uint16_t seq_con = 0;
         _pkt_build(tcb, &out_pkt, &seq_con, MSK_FIN_ACK, tcb->snd_nxt, tcb->rcv_nxt, NULL, 0);
         _pkt_setup_retransmit(tcb, out_pkt, false);
         _pkt_send(tcb, out_pkt, seq_con, false);
@@ -352,13 +353,30 @@ static int _fsm_call_close(gnrc_tcp_tcb_t *tcb)
 /**
  * @brief FSM handling function for forcefull connection teardown sequence.
  *
- * @returns   -EOPNOTSUPP. Currently not implemented.
+ * @param[in,out] tcb   TCB holding the connection information.
+ *
+ * @returns   Zero on success.
  */
-static int _fsm_call_abort(void)
+static int _fsm_call_abort(gnrc_tcp_tcb_t *tcb)
 {
     DEBUG("gnrc_tcp_fsm.c : _fsm_call_abort()\n");
-    DEBUG("gnrc_tcp_fsm.c : _fsm_call_abort() : ABORT not implemented\n");
-    return -EOPNOTSUPP;
+
+    /* A reset must be sent in case the TCB state is in one of those cases */
+    if (tcb->state == FSM_STATE_SYN_RCVD || tcb->state == FSM_STATE_ESTABLISHED ||
+        tcb->state == FSM_STATE_FIN_WAIT_1 || tcb->state == FSM_STATE_FIN_WAIT_2 ||
+        tcb->state == FSM_STATE_CLOSE_WAIT) {
+
+        /* Send RST packet without retransmit */
+        gnrc_pktsnip_t *out_pkt = NULL;
+        uint16_t seq_con = 0;
+        _pkt_build(tcb, &out_pkt, &seq_con, MSK_RST, tcb->snd_nxt, tcb->rcv_nxt, NULL, 0);
+        _pkt_send(tcb, out_pkt, seq_con, false);
+    }
+
+    /* From here on any state must transition into CLOSED state */
+    _transition_to(tcb, FSM_STATE_CLOSED);
+
+    return 0;
 }
 
 /**
@@ -827,7 +845,7 @@ static int _fsm_unprotected(gnrc_tcp_tcb_t *tcb, fsm_event_t event, gnrc_pktsnip
             ret = _fsm_call_close(tcb);
             break;
         case FSM_EVENT_CALL_ABORT :
-            ret = _fsm_call_abort();
+            ret = _fsm_call_abort(tcb);
             break;
         case FSM_EVENT_RCVD_PKT :
             ret = _fsm_rcvd_pkt(tcb, in_pkt);