[PATCH] ipcpd: Add an IPCP over DIX Ethernet

  • From: Dimitri Staessens <dimitri.staessens@xxxxxxxx>
  • To: ouroboros@xxxxxxxxxxxxx
  • Date: Sat, 10 Mar 2018 02:34:27 +0100

This adds an IPC Process that uses DIX ethernet with an Ethertype that
is configurable at bootstrap. This allows parallel DIX layers over the
same Ethernet network with different Ethertypes (and one LLC
layer). It also allows jumbo frames, and should avoid the problems we
have with some routers not handling LLC traffic very well. The
destination endpoint ID is sent as a 16 bit integer, so the maximum
payload is 1498 bytes or 8998 bytes when using Jumbo frames.

The implementation is very similar to the Ethernet LLC IPCP, so it is
implemented using preprocessor macros in the single source instead of
duplicating code.

Signed-off-by: Dimitri Staessens <dimitri.staessens@xxxxxxxx>
---
 doc/man/ouroboros.8                       |   2 +-
 include/ouroboros/ipcp.h                  |   8 +-
 src/ipcpd/CMakeLists.txt                  |   2 +-
 src/ipcpd/{eth-llc => eth}/CMakeLists.txt |  48 +-
 src/ipcpd/eth/dix.c                       |  26 +
 src/ipcpd/{eth-llc/main.c => eth/eth.c}   | 949 ++++++++++++++++++------------
 src/ipcpd/eth/llc.c                       |  26 +
 src/ipcpd/ipcp.c                          |   7 +-
 src/irmd/config.h.in                      |   1 +
 src/irmd/ipcp.c                           |   3 +
 src/lib/ipcp_config.proto                 |   6 +-
 src/lib/irm.c                             |   7 +-
 src/tools/irm/irm_ipcp_bootstrap.c        |  39 +-
 13 files changed, 724 insertions(+), 400 deletions(-)
 rename src/ipcpd/{eth-llc => eth}/CMakeLists.txt (65%)
 create mode 100644 src/ipcpd/eth/dix.c
 rename src/ipcpd/{eth-llc/main.c => eth/eth.c} (51%)
 create mode 100644 src/ipcpd/eth/llc.c

diff --git a/doc/man/ouroboros.8 b/doc/man/ouroboros.8
index a661da9..bd7b8f8 100644
--- a/doc/man/ouroboros.8
+++ b/doc/man/ouroboros.8
@@ -165,7 +165,7 @@ Values for [\fIparam\fR] are dependent on \fItype\fR:
 .PP
 \fBeth-llc\fR
 .RS 4
-if_name \fIinterface\fR specifies the interface to bind the IPCP to.
+dev \fIinterface\fR specifies the interface to bind the IPCP to.
 .PP
 [hash \fIpolicy\fR] specifies the hash function used for the directory,
 .br
diff --git a/include/ouroboros/ipcp.h b/include/ouroboros/ipcp.h
index e39137d..dc2c37f 100644
--- a/include/ouroboros/ipcp.h
+++ b/include/ouroboros/ipcp.h
@@ -38,6 +38,7 @@ enum ipcp_type {
         IPCP_NORMAL,
         IPCP_RAPTOR,
         IPCP_ETH_LLC,
+        IPCP_ETH_DIX,
         IPCP_UDP
 };
 
@@ -88,8 +89,11 @@ struct ipcp_config {
         uint32_t           ip_addr;
         uint32_t           dns_addr;
 
-        /* Ethernet LLC */
-        char *             if_name;
+        /* Ethernet */
+        char *             dev;
+
+        /* Ethernet DIX */
+        uint16_t           ethertype;
 };
 
 #endif /* OUROBOROS_IPCP_H */
diff --git a/src/ipcpd/CMakeLists.txt b/src/ipcpd/CMakeLists.txt
index 67d9fcc..d717d14 100644
--- a/src/ipcpd/CMakeLists.txt
+++ b/src/ipcpd/CMakeLists.txt
@@ -35,7 +35,7 @@ add_subdirectory(local)
 add_subdirectory(normal)
 add_subdirectory(raptor)
 add_subdirectory(udp)
-add_subdirectory(eth-llc)
+add_subdirectory(eth)
 
 configure_file("${CMAKE_CURRENT_SOURCE_DIR}/config.h.in"
   "${CMAKE_CURRENT_BINARY_DIR}/config.h" @ONLY)
diff --git a/src/ipcpd/eth-llc/CMakeLists.txt b/src/ipcpd/eth/CMakeLists.txt
similarity index 65%
rename from src/ipcpd/eth-llc/CMakeLists.txt
rename to src/ipcpd/eth/CMakeLists.txt
index 0e7f074..44062e3 100644
--- a/src/ipcpd/eth-llc/CMakeLists.txt
+++ b/src/ipcpd/eth/CMakeLists.txt
@@ -25,11 +25,11 @@ if (CMAKE_SYSTEM_NAME STREQUAL "Linux")
   if (NOT DISABLE_RAW_SOCKETS)
     message(STATUS "Raw socket support for eth-llc enabled")
     set(HAVE_RAW_SOCKETS TRUE PARENT_SCOPE)
-    set(HAVE_LLC TRUE)
+    set(HAVE_ETH TRUE)
   else ()
     message(STATUS "Raw socket support for eth-llc disabled by user")
     unset(HAVE_RAW_SOCKETS)
-    unset(HAVE_LLC)
+    unset(HAVE_ETH)
   endif ()
 endif ()
 
@@ -43,64 +43,78 @@ if (NOT CMAKE_SYSTEM_NAME STREQUAL "Linux")
 
   if (BPF_C_INCLUDE_DIR)
     set(DISABLE_BPF FALSE CACHE BOOL
-      "Disable Berkeley Packet Filter support for LLC IPCP")
+      "Disable Berkeley Packet Filter support for ETH IPCPs")
     if (NOT DISABLE_BPF)
       message(STATUS "Berkeley Packet Filter support "
-                     "for eth-llc enabled")
+                     "for ETH IPCPs enabled")
       set(HAVE_BPF TRUE PARENT_SCOPE)
-      set(HAVE_LLC TRUE)
+      set(HAVE_ETH TRUE)
     else ()
       message(STATUS "Berkeley Packet Filter support "
-                     "for eth-llc disabled by user")
+                     "for ETH IPCPs disabled by user")
       unset(HAVE_BPF)
-      unset(HAVE_LLC)
+      unset(HAVE_ETH)
     endif ()
   endif ()
 endif ()
 
 if (NETMAP_C_INCLUDE_DIR)
   set(DISABLE_NETMAP FALSE CACHE BOOL
-      "Disable netmap support for LLC IPCP")
+      "Disable netmap support for ETH IPCPs")
   if (NOT DISABLE_NETMAP)
-    message(STATUS "Netmap support for eth-llc enabled")
+    message(STATUS "Netmap support for ETH IPCPs enabled")
     set(HAVE_NETMAP TRUE PARENT_SCOPE)
     test_and_set_c_compiler_flag_global(-std=c99)
-    set(HAVE_LLC TRUE)
+    set(HAVE_ETH TRUE)
   else ()
-    message(STATUS "Netmap support for eth-llc disabled by user")
+    message(STATUS "Netmap support for ETH IPCPs disabled by user")
     unset(HAVE_NETMAP)
-    unset(HAVE_LLC)
-    unset(IPCP_ETH_LLC_TARGET CACHE)
+    unset(HAVE_ETH)
+    unset(IPCP_ETH_TARGET CACHE)
   endif ()
 endif ()
 
-if (HAVE_LLC)
-  message(STATUS "Supported raw Ethernet API found, building eth-llc")
+if (HAVE_ETH)
+  message(STATUS "Supported raw packet API found, building eth-llc and 
eth-dix")
 
   set(ETH_LLC_SOURCES
     # Add source files here
-    ${CMAKE_CURRENT_SOURCE_DIR}/main.c
+    ${CMAKE_CURRENT_SOURCE_DIR}/llc.c
   )
 
+  set(ETH_DIX_SOURCES
+    # Add source files here
+    ${CMAKE_CURRENT_SOURCE_DIR}/dix.c
+  )
+
+
   set(IPCP_ETH_LLC_TARGET ipcpd-eth-llc CACHE INTERNAL "")
+  set(IPCP_ETH_DIX_TARGET ipcpd-eth-dix CACHE INTERNAL "")
 
   add_executable(ipcpd-eth-llc ${ETH_LLC_SOURCES} ${IPCP_SOURCES})
+  add_executable(ipcpd-eth-dix ${ETH_DIX_SOURCES} ${IPCP_SOURCES})
 
   if (HAVE_BPF AND NOT APPLE)
     target_include_directories(ipcpd-eth-llc PUBLIC ${BPF_C_INCLUDE_DIR})
+    target_include_directories(ipcpd-eth-dix PUBLIC ${BPF_C_INCLUDE_DIR})
   endif ()
 
   if (HAVE_NETMAP AND NOT APPLE)
     target_include_directories(ipcpd-eth-llc PUBLIC
       ${NETMAP_C_INCLUDE_DIR})
+    target_include_directories(ipcpd-eth-dix PUBLIC
+      ${NETMAP_C_INCLUDE_DIR})
   endif ()
 
   target_link_libraries(ipcpd-eth-llc LINK_PUBLIC ouroboros-dev)
+  target_link_libraries(ipcpd-eth-dix LINK_PUBLIC ouroboros-dev)
 
   include(AddCompileFlags)
   if (CMAKE_BUILD_TYPE MATCHES "Debug*")
     add_compile_flags(ipcpd-eth-llc -DCONFIG_OUROBOROS_DEBUG)
+    add_compile_flags(ipcpd-eth-dix -DCONFIG_OUROBOROS_DEBUG)
   endif ()
 
-  install(TARGETS ipcpd-eth-llc RUNTIME DESTINATION ${CMAKE_INSTALL_SBINDIR})
+  install(TARGETS ipcpd-eth-llc ipcpd-eth-dix RUNTIME DESTINATION
+    ${CMAKE_INSTALL_SBINDIR})
 endif ()
diff --git a/src/ipcpd/eth/dix.c b/src/ipcpd/eth/dix.c
new file mode 100644
index 0000000..dfa92ea
--- /dev/null
+++ b/src/ipcpd/eth/dix.c
@@ -0,0 +1,26 @@
+/*
+ * Ouroboros - Copyright (C) 2016 - 2018
+ *
+ * IPC processes over Ethernet - DIX
+ *
+ *    Dimitri Staessens <dimitri.staessens@xxxxxxxx>
+ *    Sander Vrijders   <sander.vrijders@xxxxxxxx>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., http://www.fsf.org/about/contact/.
+ */
+
+#define BUILD_ETH_DIX
+#define OUROBOROS_PREFIX "ipcpd/eth-dix"
+
+#include "eth.c"
diff --git a/src/ipcpd/eth-llc/main.c b/src/ipcpd/eth/eth.c
similarity index 51%
rename from src/ipcpd/eth-llc/main.c
rename to src/ipcpd/eth/eth.c
index 8b20982..1f758b8 100644
--- a/src/ipcpd/eth-llc/main.c
+++ b/src/ipcpd/eth/eth.c
@@ -1,7 +1,7 @@
 /*
  * Ouroboros - Copyright (C) 2016 - 2018
  *
- * IPC process over Ethernet with LLC
+ * IPC processes over Ethernet
  *
  *    Dimitri Staessens <dimitri.staessens@xxxxxxxx>
  *    Sander Vrijders   <sander.vrijders@xxxxxxxx>
@@ -20,6 +20,10 @@
  * Foundation, Inc., http://www.fsf.org/about/contact/.
  */
 
+#if !defined(BUILD_ETH_DIX) && !defined(BUILD_ETH_LLC)
+#error Define BUILD_ETH_DIX or BUILD_ETH_LLC to build an Ethernet IPCP
+#endif
+
 #if defined(__APPLE__)
 #define _BSD_SOURCE
 #define _DARWIN_C_SOURCE
@@ -31,8 +35,6 @@
 
 #include "config.h"
 
-#define OUROBOROS_PREFIX "ipcpd/eth-llc"
-
 #include <ouroboros/hash.h>
 #include <ouroboros/errno.h>
 #include <ouroboros/list.h>
@@ -91,16 +93,27 @@
 #include <net/bpf.h>
 #endif
 
+#define MAC_SIZE                  6
+#define ETH_TYPE_LENGTH_SIZE      2
+#define ETH_HEADER_SIZE           (2 * MAC_SIZE + ETH_TYPE_LENGTH_SIZE)
+
+#if defined(BUILD_ETH_DIX)
+#define THIS_TYPE                 IPCP_ETH_DIX
+#define MGMT_EID                  0
+#define DIX_HEADER_SIZE           2
+#define MAX_EIDS                  (1 << (8 * DIX_HEADER_SIZE))
+#define ETH_MAX_SDU_SIZE          (1500 - DIX_HEADER_SIZE)
+#define ETH_FRAME_SIZE            (ETH_HEADER_SIZE + DIX_HEADER_SIZE    \
+                                   + ETH_MAX_SDU_SIZE)
+#elif defined(BUILD_ETH_LLC)
 #define THIS_TYPE                 IPCP_ETH_LLC
-
 #define MGMT_SAP                  0x01
-#define MAC_SIZE                  6
 #define LLC_HEADER_SIZE           3
 #define MAX_SAPS                  64
-#define ETH_HEADER_SIZE           (2 * MAC_SIZE + 2)
-#define ETH_FRAME_SIZE            (ETH_HEADER_SIZE + LLC_HEADER_SIZE \
-                                   + SHIM_ETH_LLC_MAX_SDU_SIZE)
-#define SHIM_ETH_LLC_MAX_SDU_SIZE (1500 - LLC_HEADER_SIZE)
+#define ETH_MAX_SDU_SIZE          (1500 - LLC_HEADER_SIZE)
+#define ETH_FRAME_SIZE            (ETH_HEADER_SIZE + LLC_HEADER_SIZE    \
+                                   + ETH_MAX_SDU_SIZE)
+#endif
 #define ALLOC_TIMEO               10    /* ms */
 #define NAME_QUERY_TIMEO          2000  /* ms */
 #define MGMT_TIMEO                100   /* ms */
@@ -112,25 +125,39 @@
 
 struct mgmt_msg {
         uint8_t code;
+#if defined(BUILD_ETH_DIX)
+        uint16_t seid;
+        uint16_t deid;
+#elif defined(BUILD_ETH_LLC)
         uint8_t ssap;
         uint8_t dsap;
+#endif
         uint8_t qoscube;
         int8_t  response;
 } __attribute__((packed));
 
-struct eth_llc_frame {
+struct eth_frame {
         uint8_t dst_hwaddr[MAC_SIZE];
         uint8_t src_hwaddr[MAC_SIZE];
-        uint8_t length[2];
+#if defined(BUILD_ETH_DIX)
+        uint8_t ethertype[ETH_TYPE_LENGTH_SIZE];
+        uint8_t eid[DIX_HEADER_SIZE];
+#elif defined(BUILD_ETH_LLC)
+        uint8_t length[ETH_TYPE_LENGTH_SIZE];
         uint8_t dsap;
         uint8_t ssap;
         uint8_t cf;
+#endif
         uint8_t payload;
 } __attribute__((packed));
 
 struct ef {
+#if defined(BUILD_ETH_DIX)
+        int32_t r_eid;
+#elif defined(BUILD_ETH_LLC)
         int8_t  sap;
         int8_t  r_sap;
+#endif
         uint8_t r_addr[MAC_SIZE];
 };
 
@@ -138,7 +165,6 @@ struct mgmt_frame {
         struct list_head next;
         uint8_t          r_addr[MAC_SIZE];
         uint8_t          buf[ETH_FRAME_SIZE];
-        size_t           len;
 };
 
 struct {
@@ -156,12 +182,15 @@ struct {
         int                s_fd;
         struct sockaddr_ll device;
 #endif /* HAVE_NETMAP */
-
+#if defined (BUILD_ETH_DIX)
+        uint16_t           ethertype;
+#elif defined(BUILD_ETH_LLC)
         struct bmp *       saps;
-        fset_t *           np1_flows;
-        fqueue_t *         fq;
         int *              ef_to_fd;
+#endif
         struct ef *        fd_to_ef;
+        fset_t *           np1_flows;
+        fqueue_t *         fq;
         pthread_rwlock_t   flows_lock;
 
         pthread_t          sdu_writer;
@@ -176,56 +205,60 @@ struct {
         pthread_mutex_t    mgmt_lock;
         pthread_cond_t     mgmt_cond;
         struct list_head   mgmt_frames;
+} eth_data;
 
-} eth_llc_data;
-
-static int eth_llc_data_init(void)
+static int eth_data_init(void)
 {
         int                i;
         int                ret = -ENOMEM;
         pthread_condattr_t cattr;
 
-        eth_llc_data.fd_to_ef =
-                malloc(sizeof(*eth_llc_data.fd_to_ef) * SYS_MAX_FLOWS);
-        if (eth_llc_data.fd_to_ef == NULL)
+        eth_data.fd_to_ef =
+                malloc(sizeof(*eth_data.fd_to_ef) * SYS_MAX_FLOWS);
+        if (eth_data.fd_to_ef == NULL)
                 goto fail_fd_to_ef;
 
-        eth_llc_data.ef_to_fd =
-                malloc(sizeof(*eth_llc_data.ef_to_fd) * MAX_SAPS);
-        if (eth_llc_data.ef_to_fd == NULL)
+#ifdef BUILD_ETH_LLC
+        eth_data.ef_to_fd =
+                malloc(sizeof(*eth_data.ef_to_fd) * MAX_SAPS);
+        if (eth_data.ef_to_fd == NULL)
                 goto fail_ef_to_fd;
 
-        eth_llc_data.saps = bmp_create(MAX_SAPS, 2);
-        if (eth_llc_data.saps == NULL)
-                goto fail_saps;
+        for (i = 0; i < MAX_SAPS; ++i)
+                eth_data.ef_to_fd[i] = -1;
 
-        eth_llc_data.np1_flows = fset_create();
-        if (eth_llc_data.np1_flows == NULL)
+        eth_data.saps = bmp_create(MAX_SAPS, 2);
+        if (eth_data.saps == NULL)
+                goto fail_saps;
+#endif
+        eth_data.np1_flows = fset_create();
+        if (eth_data.np1_flows == NULL)
                 goto fail_np1_flows;
 
-        eth_llc_data.fq = fqueue_create();
-        if (eth_llc_data.fq == NULL)
+        eth_data.fq = fqueue_create();
+        if (eth_data.fq == NULL)
                 goto fail_fq;
 
-        for (i = 0; i < MAX_SAPS; ++i)
-                eth_llc_data.ef_to_fd[i] = -1;
-
         for (i = 0; i < SYS_MAX_FLOWS; ++i) {
-                eth_llc_data.fd_to_ef[i].sap   = -1;
-                eth_llc_data.fd_to_ef[i].r_sap = -1;
-                memset(&eth_llc_data.fd_to_ef[i].r_addr, 0, MAC_SIZE);
+#if defined(BUILD_ETH_DIX)
+                eth_data.fd_to_ef[i].r_eid = -1;
+#elif defined(BUILD_ETH_LLC)
+                eth_data.fd_to_ef[i].sap   = -1;
+                eth_data.fd_to_ef[i].r_sap = -1;
+#endif
+                memset(&eth_data.fd_to_ef[i].r_addr, 0, MAC_SIZE);
         }
 
-        eth_llc_data.shim_data = shim_data_create();
-        if (eth_llc_data.shim_data == NULL)
+        eth_data.shim_data = shim_data_create();
+        if (eth_data.shim_data == NULL)
                 goto fail_shim_data;
 
         ret = -1;
 
-        if (pthread_rwlock_init(&eth_llc_data.flows_lock, NULL))
+        if (pthread_rwlock_init(&eth_data.flows_lock, NULL))
                 goto fail_flows_lock;
 
-        if (pthread_mutex_init(&eth_llc_data.mgmt_lock, NULL))
+        if (pthread_mutex_init(&eth_data.mgmt_lock, NULL))
                 goto fail_mgmt_lock;
 
         if (pthread_condattr_init(&cattr))
@@ -235,57 +268,62 @@ static int eth_llc_data_init(void)
         pthread_condattr_setclock(&cattr, PTHREAD_COND_CLOCK);
 #endif
 
-        if (pthread_cond_init(&eth_llc_data.mgmt_cond, &cattr))
+        if (pthread_cond_init(&eth_data.mgmt_cond, &cattr))
                 goto fail_mgmt_cond;
 
         pthread_condattr_destroy(&cattr);
 
-        list_head_init(&eth_llc_data.mgmt_frames);
+        list_head_init(&eth_data.mgmt_frames);
 
         return 0;
 
  fail_mgmt_cond:
         pthread_condattr_destroy(&cattr);
  fail_condattr:
-        pthread_mutex_destroy(&eth_llc_data.mgmt_lock);
+        pthread_mutex_destroy(&eth_data.mgmt_lock);
  fail_mgmt_lock:
-        pthread_rwlock_destroy(&eth_llc_data.flows_lock);
+        pthread_rwlock_destroy(&eth_data.flows_lock);
  fail_flows_lock:
-        shim_data_destroy(eth_llc_data.shim_data);
+        shim_data_destroy(eth_data.shim_data);
  fail_shim_data:
-        fqueue_destroy(eth_llc_data.fq);
+        fqueue_destroy(eth_data.fq);
  fail_fq:
-        fset_destroy(eth_llc_data.np1_flows);
+        fset_destroy(eth_data.np1_flows);
  fail_np1_flows:
-        bmp_destroy(eth_llc_data.saps);
+#ifdef BUILD_ETH_LLC
+        bmp_destroy(eth_data.saps);
  fail_saps:
-        free(eth_llc_data.ef_to_fd);
+        free(eth_data.ef_to_fd);
  fail_ef_to_fd:
-        free(eth_llc_data.fd_to_ef);
+#endif
+        free(eth_data.fd_to_ef);
  fail_fd_to_ef:
         return ret;
 }
 
-static void eth_llc_data_fini(void)
+static void eth_data_fini(void)
 {
 #if defined(HAVE_NETMAP)
-        nm_close(eth_llc_data.nmd);
+        nm_close(eth_data.nmd);
 #elif defined(HAVE_BPF)
-        close(eth_llc_data.bpf);
+        close(eth_data.bpf);
 #elif defined(HAVE_RAW_SOCKETS)
-        close(eth_llc_data.s_fd);
-#endif
-        pthread_cond_destroy(&eth_llc_data.mgmt_cond);
-        pthread_mutex_destroy(&eth_llc_data.mgmt_lock);
-        pthread_rwlock_destroy(&eth_llc_data.flows_lock);
-        shim_data_destroy(eth_llc_data.shim_data);
-        fqueue_destroy(eth_llc_data.fq);
-        fset_destroy(eth_llc_data.np1_flows);
-        bmp_destroy(eth_llc_data.saps);
-        free(eth_llc_data.fd_to_ef);
-        free(eth_llc_data.ef_to_fd);
+        close(eth_data.s_fd);
+#endif
+        pthread_cond_destroy(&eth_data.mgmt_cond);
+        pthread_mutex_destroy(&eth_data.mgmt_lock);
+        pthread_rwlock_destroy(&eth_data.flows_lock);
+        shim_data_destroy(eth_data.shim_data);
+        fqueue_destroy(eth_data.fq);
+        fset_destroy(eth_data.np1_flows);
+#ifdef BUILD_ETH_LLC
+        bmp_destroy(eth_data.saps);
+        free(eth_data.ef_to_fd);
+#endif
+        free(eth_data.fd_to_ef);
 }
 
+#ifdef BUILD_ETH_LLC
 static uint8_t reverse_bits(uint8_t b)
 {
         b = (b & 0xF0) >> 4 | (b & 0x0F) << 4;
@@ -294,66 +332,80 @@ static uint8_t reverse_bits(uint8_t b)
 
         return b;
 }
+#endif
 
-static int eth_llc_ipcp_send_frame(const uint8_t * dst_addr,
-                                   uint8_t         dsap,
-                                   uint8_t         ssap,
-                                   const uint8_t * payload,
-                                   size_t          len)
+static int eth_ipcp_send_frame(const uint8_t * dst_addr,
+#if defined(BUILD_ETH_DIX)
+                               uint16_t        deid,
+#elif defined(BUILD_ETH_LLC)
+                               uint8_t         dsap,
+                               uint8_t         ssap,
+#endif
+                               const uint8_t * payload,
+                               size_t          len)
 {
         uint32_t               frame_len = 0;
+#ifdef BUILD_ETH_LLC
         uint8_t                cf = 0x03;
         uint16_t               length;
-        uint8_t                frame[SHIM_ETH_LLC_MAX_SDU_SIZE];
-        struct eth_llc_frame * llc_frame;
+#endif
+        uint8_t                frame[ETH_MAX_SDU_SIZE];
+        struct eth_frame *     e_frame;
 
         if (payload == NULL) {
                 log_err("Payload was NULL.");
                 return -1;
         }
 
-        if (len > SHIM_ETH_LLC_MAX_SDU_SIZE)
+        if (len > ETH_MAX_SDU_SIZE)
                 return -1;
 
-        llc_frame = (struct eth_llc_frame *) frame;
+        e_frame = (struct eth_frame *) frame;
 
-        memcpy(llc_frame->dst_hwaddr, dst_addr, MAC_SIZE);
-        memcpy(llc_frame->src_hwaddr,
+        memcpy(e_frame->dst_hwaddr, dst_addr, MAC_SIZE);
+        memcpy(e_frame->src_hwaddr,
 #if defined(HAVE_NETMAP) || defined(HAVE_BPF)
-               eth_llc_data.hw_addr,
+               eth_data.hw_addr,
 #elif defined(HAVE_RAW_SOCKETS)
-               eth_llc_data.device.sll_addr,
+               eth_data.device.sll_addr,
 #endif /* HAVE_NETMAP */
                MAC_SIZE);
+#if defined(BUILD_ETH_DIX)
+        memcpy(&e_frame->ethertype, &eth_data.ethertype, ETH_TYPE_LENGTH_SIZE);
+        deid = htons(deid);
+        memcpy(&e_frame->eid, &deid, DIX_HEADER_SIZE);
+        frame_len = ETH_HEADER_SIZE + DIX_HEADER_SIZE + len;
+#elif defined(BUILD_ETH_LLC)
         length = htons(LLC_HEADER_SIZE + len);
-        memcpy(&llc_frame->length, &length, sizeof(length));
-        llc_frame->dsap = dsap;
-        llc_frame->ssap = ssap;
-        llc_frame->cf   = cf;
-        memcpy(&llc_frame->payload, payload, len);
-
+        memcpy(&e_frame->length, &length, sizeof(length));
+        e_frame->dsap = dsap;
+        e_frame->ssap = ssap;
+        e_frame->cf   = cf;
         frame_len = ETH_HEADER_SIZE + LLC_HEADER_SIZE + len;
+#endif
+        memcpy(&e_frame->payload, payload, len);
+
 #if defined(HAVE_NETMAP)
-        if (poll(&eth_llc_data.poll_out, 1, -1) < 0)
+        if (poll(&eth_data.poll_out, 1, -1) < 0)
                 return -1;
 
-        if (nm_inject(eth_llc_data.nmd, frame, frame_len) != (int) frame_len) {
+        if (nm_inject(eth_data.nmd, frame, frame_len) != (int) frame_len) {
                 log_dbg("Failed to send message.");
                 return -1;
         }
 #elif defined(HAVE_BPF)
-        if (write(eth_llc_data.bpf, frame, frame_len) < 0) {
+        if (write(eth_data.bpf, frame, frame_len) < 0) {
                 log_dbg("Failed to send message.");
                 return -1;
         }
 
 #elif defined(HAVE_RAW_SOCKETS)
-        if (sendto(eth_llc_data.s_fd,
+        if (sendto(eth_data.s_fd,
                    frame,
                    frame_len,
                    0,
-                   (struct sockaddr *) &eth_llc_data.device,
-                   sizeof(eth_llc_data.device)) <= 0) {
+                   (struct sockaddr *) &eth_data.device,
+                   sizeof(eth_data.device)) <= 0) {
                 log_dbg("Failed to send message.");
                 return -1;
         }
@@ -361,10 +413,14 @@ static int eth_llc_ipcp_send_frame(const uint8_t * 
dst_addr,
         return 0;
 }
 
-static int eth_llc_ipcp_sap_alloc(const uint8_t * dst_addr,
-                                  uint8_t         ssap,
-                                  const uint8_t * hash,
-                                  qoscube_t       cube)
+static int eth_ipcp_alloc(const uint8_t * dst_addr,
+#if defined(BUILD_ETH_DIX)
+                          uint16_t        eid,
+#elif defined(BUILD_ETH_LLC)
+                          uint8_t         ssap,
+#endif
+                          const uint8_t * hash,
+                          qoscube_t       cube)
 {
         uint8_t *         buf;
         struct mgmt_msg * msg;
@@ -379,40 +435,68 @@ static int eth_llc_ipcp_sap_alloc(const uint8_t * 
dst_addr,
 
         msg          = (struct mgmt_msg *) buf;
         msg->code    = FLOW_REQ;
+#if defined(BUILD_ETH_DIX)
+        msg->seid    = htons(eid);
+#elif defined(BUILD_ETH_LLC)
         msg->ssap    = ssap;
+#endif
         msg->qoscube = cube;
 
         memcpy(msg + 1, hash, ipcp_dir_hash_len());
 
-        ret = eth_llc_ipcp_send_frame(dst_addr, reverse_bits(MGMT_SAP),
-                                      reverse_bits(MGMT_SAP), buf, len);
-
+        ret = eth_ipcp_send_frame(dst_addr,
+#if defined(BUILD_ETH_DIX)
+                                  MGMT_EID,
+#elif defined(BUILD_ETH_LLC)
+                                  reverse_bits(MGMT_SAP),
+                                  reverse_bits(MGMT_SAP),
+#endif
+                                  buf, len);
         free(buf);
 
         return ret;
 }
 
-static int eth_llc_ipcp_sap_alloc_resp(uint8_t * dst_addr,
-                                       uint8_t   ssap,
-                                       uint8_t   dsap,
-                                       int       response)
+static int eth_ipcp_alloc_resp(uint8_t * dst_addr,
+#if defined(BUILD_ETH_DIX)
+                               uint16_t  seid,
+                               uint16_t  deid,
+#elif defined(BUILD_ETH_LLC)
+                               uint8_t   ssap,
+                               uint8_t   dsap,
+#endif
+                               int       response)
 {
         struct mgmt_msg msg;
 
         msg.code     = FLOW_REPLY;
+#if defined(BUILD_ETH_DIX)
+        msg.seid     = htons(seid);
+        msg.deid     = htons(deid);
+#elif defined(BUILD_ETH_LLC)
         msg.ssap     = ssap;
         msg.dsap     = dsap;
+#endif
         msg.response = response;
 
-        return eth_llc_ipcp_send_frame(dst_addr, reverse_bits(MGMT_SAP),
-                                       reverse_bits(MGMT_SAP),
-                                       (uint8_t *) &msg, sizeof(msg));
+        return eth_ipcp_send_frame(dst_addr,
+#if defined(BUILD_ETH_DIX)
+                                   MGMT_EID,
+#elif defined(BUILD_ETH_LLC)
+                                   reverse_bits(MGMT_SAP),
+                                   reverse_bits(MGMT_SAP),
+#endif
+                                   (uint8_t *) &msg, sizeof(msg));
 }
 
-static int eth_llc_ipcp_sap_req(uint8_t         r_sap,
-                                uint8_t *       r_addr,
-                                const uint8_t * dst,
-                                qoscube_t       cube)
+static int eth_ipcp_req(uint8_t *       r_addr,
+#if defined(BUILD_ETH_DIX)
+                        uint16_t        r_eid,
+#elif defined(BUILD_ETH_LLC)
+                        uint8_t         r_sap,
+#endif
+                        const uint8_t * dst,
+                        qoscube_t       cube)
 {
         struct timespec ts = {0, ALLOC_TIMEO * MILLION};
         struct timespec abstime;
@@ -443,50 +527,76 @@ static int eth_llc_ipcp_sap_req(uint8_t         r_sap,
                 return -1;
         }
 
-        pthread_rwlock_wrlock(&eth_llc_data.flows_lock);
+        pthread_rwlock_wrlock(&eth_data.flows_lock);
+#if defined(BUILD_ETH_DIX)
+        eth_data.fd_to_ef[fd].r_eid = r_eid;
+#elif defined(BUILD_ETH_LLC)
+        eth_data.fd_to_ef[fd].r_sap = r_sap;
+#endif
+        memcpy(eth_data.fd_to_ef[fd].r_addr, r_addr, MAC_SIZE);
 
-        eth_llc_data.fd_to_ef[fd].r_sap = r_sap;
-        memcpy(eth_llc_data.fd_to_ef[fd].r_addr, r_addr, MAC_SIZE);
+        pthread_rwlock_unlock(&eth_data.flows_lock);
 
         ipcpi.alloc_id = fd;
         pthread_cond_broadcast(&ipcpi.alloc_cond);
 
-        pthread_rwlock_unlock(&eth_llc_data.flows_lock);
         pthread_mutex_unlock(&ipcpi.alloc_lock);
 
-        log_dbg("New flow request, fd %d, remote SAP %d.", fd, r_sap);
+#if defined(BUILD_ETH_DIX)
+        log_dbg("New flow request, fd %d, remote endpoint %d.", fd, r_eid);
+#elif defined(BUILD_ETH_LLC)
+        log_dbg("New flow request, fd %d, remote endpoint %d.", fd, r_sap);
+#endif
 
         return 0;
 }
 
-static int eth_llc_ipcp_sap_alloc_reply(uint8_t   ssap,
-                                        uint8_t * r_addr,
-                                        int       dsap,
-                                        int       response)
+static int eth_ipcp_alloc_reply(uint8_t * r_addr,
+#if defined(BUILD_ETH_DIX)
+                                uint16_t  seid,
+                                uint16_t  deid,
+#elif defined(BUILD_ETH_LLC)
+                                uint8_t   ssap,
+                                int       dsap,
+#endif
+                                int       response)
 {
         int ret = 0;
         int fd = -1;
 
-        pthread_rwlock_wrlock(&eth_llc_data.flows_lock);
+        pthread_rwlock_wrlock(&eth_data.flows_lock);
 
-        fd = eth_llc_data.ef_to_fd[dsap];
+#if defined(BUILD_ETH_DIX)
+        fd = deid;
+#elif defined(BUILD_ETH_LLC)
+        fd = eth_data.ef_to_fd[dsap];
+#endif
         if (fd < 0) {
-                pthread_rwlock_unlock(& eth_llc_data.flows_lock);
+                pthread_rwlock_unlock(& eth_data.flows_lock);
                 log_err("No flow found with that SAP.");
                 return -1; /* -EFLOWNOTFOUND */
         }
 
         if (response) {
-                bmp_release(eth_llc_data.saps, eth_llc_data.fd_to_ef[fd].sap);
+#ifdef BUILD_ETH_LLC
+                bmp_release(eth_data.saps, eth_data.fd_to_ef[fd].sap);
+#endif
         } else {
-                eth_llc_data.fd_to_ef[fd].r_sap = ssap;
-                memcpy(eth_llc_data.fd_to_ef[fd].r_addr, r_addr, MAC_SIZE);
+#if defined(BUILD_ETH_DIX)
+                eth_data.fd_to_ef[fd].r_eid = seid;
+#elif defined(BUILD_ETH_LLC)
+                eth_data.fd_to_ef[fd].r_sap = ssap;
+#endif
+                memcpy(eth_data.fd_to_ef[fd].r_addr, r_addr, MAC_SIZE);
         }
 
-        pthread_rwlock_unlock(&eth_llc_data.flows_lock);
+        pthread_rwlock_unlock(&eth_data.flows_lock);
 
+#if defined(BUILD_ETH_DIX)
+        log_dbg("Flow reply, fd %d, src eid %d, dst eid %d.", fd, seid, deid);
+#elif defined(BUILD_ETH_LLC)
         log_dbg("Flow reply, fd %d, SSAP %d, DSAP %d.", fd, ssap, dsap);
-
+#endif
         if ((ret = ipcp_flow_alloc_reply(fd, response)) < 0)
                 return -1;
 
@@ -494,14 +604,14 @@ static int eth_llc_ipcp_sap_alloc_reply(uint8_t   ssap,
 
 }
 
-static int eth_llc_ipcp_name_query_req(const uint8_t * hash,
-                                       uint8_t *       r_addr)
+static int eth_ipcp_name_query_req(const uint8_t * hash,
+                                   uint8_t *       r_addr)
 {
         uint8_t *         buf;
         struct mgmt_msg * msg;
         size_t            len;
 
-        if (shim_data_reg_has(eth_llc_data.shim_data, hash)) {
+        if (shim_data_reg_has(eth_data.shim_data, hash)) {
                 len = sizeof(*msg) + ipcp_dir_hash_len();
 
                 buf = malloc(len);
@@ -513,8 +623,14 @@ static int eth_llc_ipcp_name_query_req(const uint8_t * 
hash,
 
                 memcpy(msg + 1, hash, ipcp_dir_hash_len());
 
-                if (eth_llc_ipcp_send_frame(r_addr, reverse_bits(MGMT_SAP),
-                                            reverse_bits(MGMT_SAP), buf, len)) 
{
+                if (eth_ipcp_send_frame(r_addr,
+#if defined(BUILD_ETH_DIX)
+                                        MGMT_EID,
+#elif defined(BUILD_ETH_LLC)
+                                        reverse_bits(MGMT_SAP),
+                                        reverse_bits(MGMT_SAP),
+#endif
+                                        buf, len)) {
                         log_err("Failed to send management frame.");
                         free(buf);
                         return -1;
@@ -526,22 +642,22 @@ static int eth_llc_ipcp_name_query_req(const uint8_t * 
hash,
         return 0;
 }
 
-static int eth_llc_ipcp_name_query_reply(const uint8_t * hash,
-                                         uint8_t *       r_addr)
+static int eth_ipcp_name_query_reply(const uint8_t * hash,
+                                     uint8_t *       r_addr)
 {
         uint64_t address = 0;
 
         memcpy(&address, r_addr, MAC_SIZE);
 
-        shim_data_dir_add_entry(eth_llc_data.shim_data, hash, address);
+        shim_data_dir_add_entry(eth_data.shim_data, hash, address);
 
-        shim_data_dir_query_respond(eth_llc_data.shim_data, hash);
+        shim_data_dir_query_respond(eth_data.shim_data, hash);
 
         return 0;
 }
 
-static int eth_llc_ipcp_mgmt_frame(const uint8_t * buf,
-                                   uint8_t *       r_addr)
+static int eth_ipcp_mgmt_frame(const uint8_t * buf,
+                               uint8_t *       r_addr)
 {
         struct mgmt_msg * msg;
 
@@ -549,25 +665,34 @@ static int eth_llc_ipcp_mgmt_frame(const uint8_t * buf,
 
         switch (msg->code) {
         case FLOW_REQ:
-                if (shim_data_reg_has(eth_llc_data.shim_data,
+                if (shim_data_reg_has(eth_data.shim_data,
                                       buf + sizeof(*msg))) {
-                        eth_llc_ipcp_sap_req(msg->ssap,
-                                             r_addr,
-                                             buf + sizeof(*msg),
-                                             msg->qoscube);
+                        eth_ipcp_req(r_addr,
+#if defined(BUILD_ETH_DIX)
+                                     ntohs(msg->seid),
+#elif defined(BUILD_ETH_LLC)
+                                     msg->ssap,
+#endif
+                                     buf + sizeof(*msg),
+                                     msg->qoscube);
                 }
                 break;
         case FLOW_REPLY:
-                eth_llc_ipcp_sap_alloc_reply(msg->ssap,
-                                             r_addr,
-                                             msg->dsap,
-                                             msg->response);
+                eth_ipcp_alloc_reply(r_addr,
+#if defined(BUILD_ETH_DIX)
+                                     ntohs(msg->seid),
+                                     ntohs(msg->deid),
+#elif defined(BUILD_ETH_LLC)
+                                     msg->ssap,
+                                     msg->dsap,
+#endif
+                                     msg->response);
                 break;
         case NAME_QUERY_REQ:
-                eth_llc_ipcp_name_query_req(buf + sizeof(*msg), r_addr);
+                eth_ipcp_name_query_req(buf + sizeof(*msg), r_addr);
                 break;
         case NAME_QUERY_REPLY:
-                eth_llc_ipcp_name_query_reply(buf + sizeof(*msg), r_addr);
+                eth_ipcp_name_query_reply(buf + sizeof(*msg), r_addr);
                 break;
         default:
                 log_err("Unknown message received %d.", msg->code);
@@ -577,7 +702,7 @@ static int eth_llc_ipcp_mgmt_frame(const uint8_t * buf,
         return 0;
 }
 
-static void * eth_llc_ipcp_mgmt_handler(void * o)
+static void * eth_ipcp_mgmt_handler(void * o)
 {
         int                 ret;
         struct timespec     timeout = {(MGMT_TIMEO / 1000),
@@ -588,7 +713,7 @@ static void * eth_llc_ipcp_mgmt_handler(void * o)
         (void) o;
 
         pthread_cleanup_push((void (*)(void *)) pthread_mutex_unlock,
-                             (void *) &eth_llc_data.mgmt_lock);
+                             (void *) &eth_data.mgmt_lock);
 
         while (true) {
                 ret = 0;
@@ -596,30 +721,30 @@ static void * eth_llc_ipcp_mgmt_handler(void * o)
                 clock_gettime(PTHREAD_COND_CLOCK, &abstime);
                 ts_add(&abstime, &timeout, &abstime);
 
-                pthread_mutex_lock(&eth_llc_data.mgmt_lock);
+                pthread_mutex_lock(&eth_data.mgmt_lock);
 
-                while (list_is_empty(&eth_llc_data.mgmt_frames) &&
+                while (list_is_empty(&eth_data.mgmt_frames) &&
                        ret != -ETIMEDOUT)
-                        ret = -pthread_cond_timedwait(&eth_llc_data.mgmt_cond,
-                                                      &eth_llc_data.mgmt_lock,
+                        ret = -pthread_cond_timedwait(&eth_data.mgmt_cond,
+                                                      &eth_data.mgmt_lock,
                                                       &abstime);
 
                 if (ret == -ETIMEDOUT) {
-                        pthread_mutex_unlock(&eth_llc_data.mgmt_lock);
+                        pthread_mutex_unlock(&eth_data.mgmt_lock);
                         continue;
                 }
 
-                frame = list_first_entry((&eth_llc_data.mgmt_frames),
+                frame = list_first_entry((&eth_data.mgmt_frames),
                                          struct mgmt_frame, next);
                 if (frame == NULL) {
-                        pthread_mutex_unlock(&eth_llc_data.mgmt_lock);
+                        pthread_mutex_unlock(&eth_data.mgmt_lock);
                         continue;
                 }
 
                 list_del(&frame->next);
-                pthread_mutex_unlock(&eth_llc_data.mgmt_lock);
+                pthread_mutex_unlock(&eth_data.mgmt_lock);
 
-                eth_llc_ipcp_mgmt_frame(frame->buf, frame->r_addr);
+                eth_ipcp_mgmt_frame(frame->buf, frame->r_addr);
                 free(frame);
         }
 
@@ -628,24 +753,28 @@ static void * eth_llc_ipcp_mgmt_handler(void * o)
         return (void *) 0;
 }
 
-static void * eth_llc_ipcp_sdu_reader(void * o)
+static void * eth_ipcp_sdu_reader(void * o)
 {
-        uint8_t                br_addr[MAC_SIZE];
-        uint16_t               length;
-        uint8_t                dsap;
-        uint8_t                ssap;
-        int                    fd;
+        uint8_t             br_addr[MAC_SIZE];
+#if defined(BUILD_ETH_DIX)
+        uint16_t            deid;
+#elif defined(BUILD_ETH_LLC)
+        uint8_t             dsap;
+        uint8_t             ssap;
+#endif
+        uint16_t            length;
+        int                 fd;
 #if defined(HAVE_NETMAP)
-        uint8_t *              buf;
-        struct nm_pkthdr       hdr;
+        uint8_t *           buf;
+        struct nm_pkthdr    hdr;
 #elif defined(HAVE_BPF)
-        uint8_t                buf[BPF_BLEN];
+        uint8_t             buf[BPF_BLEN];
 #elif defined(HAVE_RAW_SOCKETS)
-        uint8_t                buf[ETH_FRAME_SIZE];
+        uint8_t             buf[ETH_FRAME_SIZE];
 #endif
-        int                    frame_len = 0;
-        struct eth_llc_frame * llc_frame;
-        struct mgmt_frame *    frame;
+        int                 frame_len = 0;
+        struct eth_frame *  e_frame;
+        struct mgmt_frame * frame;
 
         (void) o;
 
@@ -653,45 +782,53 @@ static void * eth_llc_ipcp_sdu_reader(void * o)
 
         while (true) {
 #if defined(HAVE_NETMAP)
-                if (poll(&eth_llc_data.poll_in, 1, -1) < 0)
+                if (poll(&eth_data.poll_in, 1, -1) < 0)
                         continue;
-                if (eth_llc_data.poll_in.revents == 0) /* TIMED OUT */
+                if (eth_data.poll_in.revents == 0) /* TIMED OUT */
                         continue;
 
-                buf = nm_nextpkt(eth_llc_data.nmd, &hdr);
+                buf = nm_nextpkt(eth_data.nmd, &hdr);
                 if (buf == NULL) {
                         log_err("Bad read from netmap device.");
                         continue;
                 }
 #elif defined(HAVE_BPF)
-                frame_len = read(eth_llc_data.bpf, buf, BPF_BLEN);
+                frame_len = read(eth_data.bpf, buf, BPF_BLEN);
 #elif defined(HAVE_RAW_SOCKETS)
-                frame_len = recv(eth_llc_data.s_fd, buf,
-                                 SHIM_ETH_LLC_MAX_SDU_SIZE, 0);
+                frame_len = recv(eth_data.s_fd, buf,
+                                 ETH_MAX_SDU_SIZE, 0);
 #endif
                 if (frame_len <= 0)
                         continue;
 
 #if defined(HAVE_BPF) && !defined(HAVE_NETMAP)
-                llc_frame = (struct eth_llc_frame *)
+                e_frame = (struct eth_frame *)
                         (buf + ((struct bpf_hdr *) buf)->bh_hdrlen);
 #else
-                llc_frame = (struct eth_llc_frame *) buf;
+                e_frame = (struct eth_frame *) buf;
 #endif
-                assert(llc_frame->dst_hwaddr);
+                assert(e_frame->dst_hwaddr);
 
 #if !defined(HAVE_BPF)
     #if defined(HAVE_NETMAP)
-                if (memcmp(eth_llc_data.hw_addr,
+                if (memcmp(eth_data.hw_addr,
     #elif defined(HAVE_RAW_SOCKETS)
-                if (memcmp(eth_llc_data.device.sll_addr,
+                if (memcmp(eth_data.device.sll_addr,
     #endif /* HAVE_NETMAP */
-                           llc_frame->dst_hwaddr,
+                           e_frame->dst_hwaddr,
                            MAC_SIZE) &&
-                    memcmp(br_addr, llc_frame->dst_hwaddr, MAC_SIZE)) {
+                    memcmp(br_addr, e_frame->dst_hwaddr, MAC_SIZE)) {
                 }
 #endif
-                memcpy(&length, &llc_frame->length, sizeof(length));
+
+#if defined(BUILD_ETH_DIX)
+                length = frame_len - ETH_HEADER_SIZE - DIX_HEADER_SIZE;
+                memcpy(&deid, &e_frame->eid, sizeof(deid));
+                deid = ntohs(deid);
+
+                if (deid == MGMT_EID) {
+#elif defined (BUILD_ETH_LLC)
+                memcpy(&length, &e_frame->length, sizeof(length));
                 length = ntohs(length);
 
                 if (length > 0x05FF) /* DIX */
@@ -699,82 +836,100 @@ static void * eth_llc_ipcp_sdu_reader(void * o)
 
                 length -= LLC_HEADER_SIZE;
 
-                dsap = reverse_bits(llc_frame->dsap);
-                ssap = reverse_bits(llc_frame->ssap);
+                dsap = reverse_bits(e_frame->dsap);
+                ssap = reverse_bits(e_frame->ssap);
 
                 if (ssap == MGMT_SAP && dsap == MGMT_SAP) {
-                        pthread_mutex_lock(&eth_llc_data.mgmt_lock);
+#endif
+                        pthread_mutex_lock(&eth_data.mgmt_lock);
 
                         frame = malloc(sizeof(*frame));
                         if (frame == NULL) {
-                                pthread_mutex_unlock(&eth_llc_data.mgmt_lock);
+                                pthread_mutex_unlock(&eth_data.mgmt_lock);
                                 continue;
                         }
 
-                        memcpy(frame->buf, &llc_frame->payload, length);
-                        memcpy(frame->r_addr, llc_frame->src_hwaddr, MAC_SIZE);
-                        frame->len = length;
-                        list_add(&frame->next, &eth_llc_data.mgmt_frames);
-                        pthread_cond_signal(&eth_llc_data.mgmt_cond);
-                        pthread_mutex_unlock(&eth_llc_data.mgmt_lock);
+                        memcpy(frame->buf, &e_frame->payload, length);
+                        memcpy(frame->r_addr, e_frame->src_hwaddr, MAC_SIZE);
+                        list_add(&frame->next, &eth_data.mgmt_frames);
+                        pthread_cond_signal(&eth_data.mgmt_cond);
+                        pthread_mutex_unlock(&eth_data.mgmt_lock);
                 } else {
-                        pthread_rwlock_rdlock(&eth_llc_data.flows_lock);
+                        pthread_rwlock_rdlock(&eth_data.flows_lock);
 
-                        fd = eth_llc_data.ef_to_fd[dsap];
+#if defined(BUILD_ETH_DIX)
+                        fd = deid;
+#elif defined(BUILD_ETH_LLC)
+                        fd = eth_data.ef_to_fd[dsap];
+#endif
                         if (fd < 0) {
-                                
pthread_rwlock_unlock(&eth_llc_data.flows_lock);
+                                pthread_rwlock_unlock(&eth_data.flows_lock);
                                 continue;
                         }
 
-                        if (eth_llc_data.fd_to_ef[fd].r_sap != ssap
-                            || memcmp(eth_llc_data.fd_to_ef[fd].r_addr,
-                                      llc_frame->src_hwaddr, MAC_SIZE)) {
-                                
pthread_rwlock_unlock(&eth_llc_data.flows_lock);
+#ifdef BUILD_ETH_LLC
+                        if (eth_data.fd_to_ef[fd].r_sap != ssap
+                            || memcmp(eth_data.fd_to_ef[fd].r_addr,
+                                      e_frame->src_hwaddr, MAC_SIZE)) {
+                                pthread_rwlock_unlock(&eth_data.flows_lock);
                                 continue;
                         }
+#endif
+                        pthread_rwlock_unlock(&eth_data.flows_lock);
 
-                        pthread_rwlock_unlock(&eth_llc_data.flows_lock);
-
-                        flow_write(fd, &llc_frame->payload, length);
+                        flow_write(fd, &e_frame->payload, length);
                 }
         }
 
         return (void *) 0;
 }
 
-static void * eth_llc_ipcp_sdu_writer(void * o)
+static void * eth_ipcp_sdu_writer(void * o)
 {
         int                  fd;
         struct shm_du_buff * sdb;
-        uint8_t              ssap;
+#if defined(BUILD_ETH_DIX)
+        uint16_t             deid;
+#elif defined(BUILD_ETH_LLC)
         uint8_t              dsap;
+        uint8_t              ssap;
+#endif
         uint8_t              r_addr[MAC_SIZE];
 
         (void) o;
 
         while (true) {
-                fevent(eth_llc_data.np1_flows, eth_llc_data.fq, NULL);
+                fevent(eth_data.np1_flows, eth_data.fq, NULL);
 
-                pthread_rwlock_rdlock(&eth_llc_data.flows_lock);
-                while ((fd = fqueue_next(eth_llc_data.fq)) >= 0) {
+                pthread_rwlock_rdlock(&eth_data.flows_lock);
+                while ((fd = fqueue_next(eth_data.fq)) >= 0) {
                         if (ipcp_flow_read(fd, &sdb)) {
                                 log_err("Bad read from fd %d.", fd);
                                 continue;
                         }
 
-                        ssap = reverse_bits(eth_llc_data.fd_to_ef[fd].sap);
-                        dsap = reverse_bits(eth_llc_data.fd_to_ef[fd].r_sap);
+#if defined(BUILD_ETH_DIX)
+                        deid = eth_data.fd_to_ef[fd].r_eid;
+#elif defined(BUILD_ETH_LLC)
+                        dsap = reverse_bits(eth_data.fd_to_ef[fd].r_sap);
+                        ssap = reverse_bits(eth_data.fd_to_ef[fd].sap);
+#endif
                         memcpy(r_addr,
-                               eth_llc_data.fd_to_ef[fd].r_addr,
+                               eth_data.fd_to_ef[fd].r_addr,
                                MAC_SIZE);
 
-                        eth_llc_ipcp_send_frame(r_addr, dsap, ssap,
-                                                shm_du_buff_head(sdb),
-                                                shm_du_buff_tail(sdb)
-                                                - shm_du_buff_head(sdb));
+                        eth_ipcp_send_frame(r_addr,
+#if defined(BUILD_ETH_DIX)
+                                            deid,
+#elif defined(BUILD_ETH_LLC)
+                                            dsap, ssap,
+#endif
+                                            shm_du_buff_head(sdb),
+                                            shm_du_buff_tail(sdb)
+                                            - shm_du_buff_head(sdb));
                         ipcp_sdb_release(sdb);
                 }
-                pthread_rwlock_unlock(&eth_llc_data.flows_lock);
+                pthread_rwlock_unlock(&eth_data.flows_lock);
         }
 
         return (void *) 1;
@@ -808,21 +963,31 @@ static void change_flows_state(bool up)
         int      i;
         uint32_t flags;
 
-        pthread_rwlock_rdlock(&eth_llc_data.flows_lock);
+        pthread_rwlock_rdlock(&eth_data.flows_lock);
 
-        for (i = 0; i < MAX_SAPS; i++) {
-                if (eth_llc_data.ef_to_fd[i] != -1) {
+#if defined(BUILD_ETH_DIX)
+        for (i = 0; i < SYS_MAX_FLOWS; ++i)
+                if (eth_data.fd_to_ef[i].r_eid != -1) {
                         fccntl(i, FLOWGFLAGS, &flags);
                         if (up)
-                                fccntl(eth_llc_data.ef_to_fd[i],
+                                fccntl(i, FLOWSFLAGS, flags & ~FLOWFDOWN);
+                        else
+                                fccntl(i, FLOWSFLAGS, flags | FLOWFDOWN);
+                }
+#elif defined(BUILD_ETH_LLC)
+        for (i = 0; i < MAX_SAPS; i++)
+                if (eth_data.ef_to_fd[i] != -1) {
+                        fccntl(eth_data.ef_to_fd[i], FLOWGFLAGS, &flags);
+                        if (up)
+                                fccntl(eth_data.ef_to_fd[i],
                                        FLOWSFLAGS, flags & ~FLOWFDOWN);
                         else
-                                fccntl(eth_llc_data.ef_to_fd[i],
+                                fccntl(eth_data.ef_to_fd[i],
                                        FLOWSFLAGS, flags | FLOWFDOWN);
                 }
-        }
+#endif
 
-        pthread_rwlock_unlock(&eth_llc_data.flows_lock);
+        pthread_rwlock_unlock(&eth_data.flows_lock);
 }
 
 static void close_ptr(void * o)
@@ -831,7 +996,7 @@ static void close_ptr(void * o)
 }
 
 
-static void * eth_llc_ipcp_if_monitor(void * o)
+static void * eth_ipcp_if_monitor(void * o)
 {
         int                fd;
         int                status;
@@ -877,7 +1042,7 @@ static void * eth_llc_ipcp_if_monitor(void * o)
                         ifi = NLMSG_DATA(h);
 
                         /* Not our interface */
-                        if (ifi->ifi_index != eth_llc_data.device.sll_ifindex)
+                        if (ifi->ifi_index != eth_data.device.sll_ifindex)
                                 continue;
 
                         if (ifi->ifi_flags & IFF_UP) {
@@ -916,7 +1081,7 @@ static int open_bpf_device(void)
 }
 #endif
 
-static int eth_llc_ipcp_bootstrap(const struct ipcp_config * conf)
+static int eth_ipcp_bootstrap(const struct ipcp_config * conf)
 {
         int              idx;
         struct ifreq     ifr;
@@ -937,13 +1102,17 @@ static int eth_llc_ipcp_bootstrap(const struct 
ipcp_config * conf)
         assert(conf);
         assert(conf->type == THIS_TYPE);
 
-        if (conf->if_name == NULL) {
-                log_err("Interface name is NULL.");
+        if (conf->dev == NULL) {
+                log_err("Device name is NULL.");
                 return -1;
         }
 
         memset(&ifr, 0, sizeof(ifr));
-        memcpy(ifr.ifr_name, conf->if_name, strlen(conf->if_name));
+        memcpy(ifr.ifr_name, conf->dev, strlen(conf->dev));
+
+#ifdef BUILD_ETH_DIX
+        eth_data.ethertype = htons(conf->ethertype);
+#endif
 
 #if defined(__FreeBSD__) || defined(__APPLE__)
         if (getifaddrs(&ifaddr) < 0)  {
@@ -952,12 +1121,12 @@ static int eth_llc_ipcp_bootstrap(const struct 
ipcp_config * conf)
         }
 
         for (ifa = ifaddr, idx = 0; ifa != NULL; ifa = ifa->ifa_next, ++idx) {
-                if (strcmp(ifa->ifa_name, conf->if_name))
+                if (strcmp(ifa->ifa_name, conf->dev))
                         continue;
-                log_dbg("Interface %s found.", conf->if_name);
+                log_dbg("Interface %s found.", conf->dev);
 
     #if defined(HAVE_NETMAP) || defined(HAVE_BPF)
-                memcpy(eth_llc_data.hw_addr,
+                memcpy(eth_data.hw_addr,
                        LLADDR((struct sockaddr_dl *) (ifa)->ifa_addr),
                        MAC_SIZE);
     #elif defined (HAVE_RAW_SOCKETS)
@@ -988,7 +1157,7 @@ static int eth_llc_ipcp_bootstrap(const struct ipcp_config 
* conf)
 
         close(skfd);
 
-        idx = if_nametoindex(conf->if_name);
+        idx = if_nametoindex(conf->dev);
         if (idx == 0) {
                 log_err("Failed to retrieve interface index.");
                 close(skfd);
@@ -998,76 +1167,76 @@ static int eth_llc_ipcp_bootstrap(const struct 
ipcp_config * conf)
 
 #if defined(HAVE_NETMAP)
         strcpy(ifn, "netmap:");
-        strcat(ifn, conf->if_name);
+        strcat(ifn, conf->dev);
 
-        eth_llc_data.nmd = nm_open(ifn, NULL, 0, NULL);
-        if (eth_llc_data.nmd == NULL) {
+        eth_data.nmd = nm_open(ifn, NULL, 0, NULL);
+        if (eth_data.nmd == NULL) {
                 log_err("Failed to open netmap device.");
                 return -1;
         }
 
-        memset(&eth_llc_data.poll_in, 0, sizeof(eth_llc_data.poll_in));
-        memset(&eth_llc_data.poll_out, 0, sizeof(eth_llc_data.poll_out));
+        memset(&eth_data.poll_in, 0, sizeof(eth_data.poll_in));
+        memset(&eth_data.poll_out, 0, sizeof(eth_data.poll_out));
 
-        eth_llc_data.poll_in.fd      = NETMAP_FD(eth_llc_data.nmd);
-        eth_llc_data.poll_in.events  = POLLIN;
-        eth_llc_data.poll_out.fd     = NETMAP_FD(eth_llc_data.nmd);
-        eth_llc_data.poll_out.events = POLLOUT;
+        eth_data.poll_in.fd      = NETMAP_FD(eth_data.nmd);
+        eth_data.poll_in.events  = POLLIN;
+        eth_data.poll_out.fd     = NETMAP_FD(eth_data.nmd);
+        eth_data.poll_out.events = POLLOUT;
 
         log_info("Using netmap device.");
 #elif defined(HAVE_BPF) /* !HAVE_NETMAP */
-        eth_llc_data.bpf = open_bpf_device();
-        if (eth_llc_data.bpf < 0) {
+        eth_data.bpf = open_bpf_device();
+        if (eth_data.bpf < 0) {
                 log_err("Failed to open bpf device.");
                 return -1;
         }
 
-        ioctl(eth_llc_data.bpf, BIOCGBLEN, &blen);
+        ioctl(eth_data.bpf, BIOCGBLEN, &blen);
         if (BPF_BLEN < blen) {
                 log_err("BPF buffer too small (is: %ld must be: %d).",
                         BPF_BLEN, blen);
                 goto fail_device;
         }
 
-        if (ioctl(eth_llc_data.bpf, BIOCSETIF, &ifr) < 0) {
+        if (ioctl(eth_data.bpf, BIOCSETIF, &ifr) < 0) {
                 log_err("Failed to set interface.");
                 goto fail_device;
         }
 
-        if (ioctl(eth_llc_data.bpf, BIOCSHDRCMPLT, &enable) < 0) {
+        if (ioctl(eth_data.bpf, BIOCSHDRCMPLT, &enable) < 0) {
                 log_err("Failed to set BIOCSHDRCMPLT.");
                 goto fail_device;
         }
 
-        if (ioctl(eth_llc_data.bpf, BIOCSSEESENT, &disable) < 0) {
+        if (ioctl(eth_data.bpf, BIOCSSEESENT, &disable) < 0) {
                 log_err("Failed to set BIOCSSEESENT.");
                 goto fail_device;
         }
 
-        if (ioctl(eth_llc_data.bpf, BIOCIMMEDIATE, &enable) < 0) {
+        if (ioctl(eth_data.bpf, BIOCIMMEDIATE, &enable) < 0) {
                 log_err("Failed to set BIOCIMMEDIATE.");
                 goto fail_device;
         }
 
         log_info("Using Berkeley Packet Filter.");
 #elif defined(HAVE_RAW_SOCKETS)
-        memset(&(eth_llc_data.device), 0, sizeof(eth_llc_data.device));
-        eth_llc_data.device.sll_ifindex  = idx;
-        eth_llc_data.device.sll_family   = AF_PACKET;
-        memcpy(eth_llc_data.device.sll_addr, ifr.ifr_hwaddr.sa_data, MAC_SIZE);
-        eth_llc_data.device.sll_halen    = MAC_SIZE;
-        eth_llc_data.device.sll_protocol = htons(ETH_P_ALL);
-        eth_llc_data.s_fd = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_802_2));
+        memset(&(eth_data.device), 0, sizeof(eth_data.device));
+        eth_data.device.sll_ifindex  = idx;
+        eth_data.device.sll_family   = AF_PACKET;
+        memcpy(eth_data.device.sll_addr, ifr.ifr_hwaddr.sa_data, MAC_SIZE);
+        eth_data.device.sll_halen    = MAC_SIZE;
+        eth_data.device.sll_protocol = htons(ETH_P_ALL);
+        eth_data.s_fd = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_802_2));
 
         log_info("Using raw socket device.");
 
-        if (eth_llc_data.s_fd < 0) {
+        if (eth_data.s_fd < 0) {
                 log_err("Failed to create socket.");
                 return -1;
         }
 
-        if (bind(eth_llc_data.s_fd, (struct sockaddr *) &eth_llc_data.device,
-                sizeof(eth_llc_data.device))) {
+        if (bind(eth_data.s_fd, (struct sockaddr *) &eth_data.device,
+                sizeof(eth_data.device))) {
                 log_err("Failed to bind socket to interface");
                 goto fail_device;
         }
@@ -1076,71 +1245,76 @@ static int eth_llc_ipcp_bootstrap(const struct 
ipcp_config * conf)
         ipcp_set_state(IPCP_OPERATIONAL);
 
 #ifdef __linux__
-        if (pthread_create(&eth_llc_data.if_monitor,
+        if (pthread_create(&eth_data.if_monitor,
                            NULL,
-                           eth_llc_ipcp_if_monitor,
+                           eth_ipcp_if_monitor,
                            NULL)) {
                 ipcp_set_state(IPCP_INIT);
                 goto fail_device;
         }
 #endif
 
-        if (pthread_create(&eth_llc_data.mgmt_handler,
+        if (pthread_create(&eth_data.mgmt_handler,
                            NULL,
-                           eth_llc_ipcp_mgmt_handler,
+                           eth_ipcp_mgmt_handler,
                            NULL)) {
                 ipcp_set_state(IPCP_INIT);
                 goto fail_mgmt_handler;
         }
 
-        if (pthread_create(&eth_llc_data.sdu_reader,
+        if (pthread_create(&eth_data.sdu_reader,
                            NULL,
-                           eth_llc_ipcp_sdu_reader,
+                           eth_ipcp_sdu_reader,
                            NULL)) {
                 ipcp_set_state(IPCP_INIT);
                 goto fail_sdu_reader;
         }
 
-        if (pthread_create(&eth_llc_data.sdu_writer,
+        if (pthread_create(&eth_data.sdu_writer,
                            NULL,
-                           eth_llc_ipcp_sdu_writer,
+                           eth_ipcp_sdu_writer,
                            NULL)) {
                 ipcp_set_state(IPCP_INIT);
                 goto fail_sdu_writer;
         }
 
+#if defined(BUILD_ETH_DIX)
+        log_dbg("Bootstrapped IPCP over DIX Ethernet with pid %d "
+                "and Ethertype 0x%X.", getpid(), conf->ethertype);
+#elif defined(BUILD_ETH_LLC)
         log_dbg("Bootstrapped IPCP over Ethernet with LLC with pid %d.",
                 getpid());
+#endif
 
         return 0;
 
  fail_sdu_writer:
-        pthread_cancel(eth_llc_data.sdu_reader);
-        pthread_join(eth_llc_data.sdu_reader, NULL);
+        pthread_cancel(eth_data.sdu_reader);
+        pthread_join(eth_data.sdu_reader, NULL);
  fail_sdu_reader:
-        pthread_cancel(eth_llc_data.mgmt_handler);
-        pthread_join(eth_llc_data.mgmt_handler, NULL);
+        pthread_cancel(eth_data.mgmt_handler);
+        pthread_join(eth_data.mgmt_handler, NULL);
  fail_mgmt_handler:
 #if defined(__linux__)
-        pthread_cancel(eth_llc_data.if_monitor);
-        pthread_join(eth_llc_data.if_monitor, NULL);
+        pthread_cancel(eth_data.if_monitor);
+        pthread_join(eth_data.if_monitor, NULL);
 #endif
 #if !defined(HAVE_NETMAP)
  fail_device:
 #endif
 #if defined(HAVE_NETMAP)
-        nm_close(eth_llc_data.nmd);
+        nm_close(eth_data.nmd);
 #elif defined(HAVE_BPF)
-        close(eth_llc_data.bpf);
+        close(eth_data.bpf);
 #elif defined(HAVE_RAW_SOCKETS)
-        close(eth_llc_data.s_fd);
+        close(eth_data.s_fd);
 #endif
         return -1;
 }
 
-static int eth_llc_ipcp_reg(const uint8_t * hash)
+static int eth_ipcp_reg(const uint8_t * hash)
 {
-        if (shim_data_reg_add_entry(eth_llc_data.shim_data, hash)) {
+        if (shim_data_reg_add_entry(eth_data.shim_data, hash)) {
                 log_err("Failed to add " HASH_FMT " to local registry.",
                         HASH_VAL(hash));
                 return -1;
@@ -1151,14 +1325,14 @@ static int eth_llc_ipcp_reg(const uint8_t * hash)
         return 0;
 }
 
-static int eth_llc_ipcp_unreg(const uint8_t * hash)
+static int eth_ipcp_unreg(const uint8_t * hash)
 {
-        shim_data_reg_del_entry(eth_llc_data.shim_data, hash);
+        shim_data_reg_del_entry(eth_data.shim_data, hash);
 
         return 0;
 }
 
-static int eth_llc_ipcp_query(const uint8_t * hash)
+static int eth_ipcp_query(const uint8_t * hash)
 {
         uint8_t            r_addr[MAC_SIZE];
         struct timespec    timeout = {(NAME_QUERY_TIMEO / 1000),
@@ -1169,7 +1343,7 @@ static int eth_llc_ipcp_query(const uint8_t * hash)
         struct mgmt_msg *  msg;
         size_t             len;
 
-        if (shim_data_dir_has(eth_llc_data.shim_data, hash))
+        if (shim_data_dir_has(eth_data.shim_data, hash))
                 return 0;
 
         len = sizeof(*msg) + ipcp_dir_hash_len();
@@ -1185,16 +1359,22 @@ static int eth_llc_ipcp_query(const uint8_t * hash)
 
         memset(r_addr, 0xff, MAC_SIZE);
 
-        query = shim_data_dir_query_create(eth_llc_data.shim_data, hash);
+        query = shim_data_dir_query_create(eth_data.shim_data, hash);
         if (query == NULL) {
                 free(buf);
                 return -1;
         }
 
-        if (eth_llc_ipcp_send_frame(r_addr, reverse_bits(MGMT_SAP),
-                                    reverse_bits(MGMT_SAP), buf, len)) {
+        if (eth_ipcp_send_frame(r_addr,
+#if defined(BUILD_ETH_DIX)
+                                MGMT_EID,
+#elif defined(BUILD_ETH_LLC)
+                                reverse_bits(MGMT_SAP),
+                                reverse_bits(MGMT_SAP),
+#endif
+                                buf, len)) {
                 log_err("Failed to send management frame.");
-                shim_data_dir_query_destroy(eth_llc_data.shim_data, query);
+                shim_data_dir_query_destroy(eth_data.shim_data, query);
                 free(buf);
                 return -1;
         }
@@ -1203,16 +1383,18 @@ static int eth_llc_ipcp_query(const uint8_t * hash)
 
         ret = shim_data_dir_query_wait(query, &timeout);
 
-        shim_data_dir_query_destroy(eth_llc_data.shim_data, query);
+        shim_data_dir_query_destroy(eth_data.shim_data, query);
 
         return ret;
 }
 
-static int eth_llc_ipcp_flow_alloc(int             fd,
-                                   const uint8_t * hash,
-                                   qoscube_t       cube)
+static int eth_ipcp_flow_alloc(int             fd,
+                               const uint8_t * hash,
+                               qoscube_t       cube)
 {
+#ifdef BUILD_ETH_LLC
         uint8_t  ssap = 0;
+#endif
         uint8_t  r_addr[MAC_SIZE];
         uint64_t addr = 0;
 
@@ -1225,50 +1407,64 @@ static int eth_llc_ipcp_flow_alloc(int             fd,
                 return -1;
         }
 
-        if (!shim_data_dir_has(eth_llc_data.shim_data, hash)) {
+        if (!shim_data_dir_has(eth_data.shim_data, hash)) {
                 log_err("Destination unreachable.");
                 return -1;
         }
-        addr = shim_data_dir_get_addr(eth_llc_data.shim_data, hash);
+        addr = shim_data_dir_get_addr(eth_data.shim_data, hash);
 
-        pthread_rwlock_wrlock(&eth_llc_data.flows_lock);
-
-        ssap =  bmp_allocate(eth_llc_data.saps);
-        if (!bmp_is_id_valid(eth_llc_data.saps, ssap)) {
-                pthread_rwlock_unlock(&eth_llc_data.flows_lock);
+        pthread_rwlock_wrlock(&eth_data.flows_lock);
+#ifdef BUILD_ETH_LLC
+        ssap =  bmp_allocate(eth_data.saps);
+        if (!bmp_is_id_valid(eth_data.saps, ssap)) {
+                pthread_rwlock_unlock(&eth_data.flows_lock);
                 return -1;
         }
 
-        eth_llc_data.fd_to_ef[fd].sap = ssap;
-        eth_llc_data.ef_to_fd[ssap]   = fd;
-
-        pthread_rwlock_unlock(&eth_llc_data.flows_lock);
+        eth_data.fd_to_ef[fd].sap = ssap;
+        eth_data.ef_to_fd[ssap]   = fd;
+#endif
+        pthread_rwlock_unlock(&eth_data.flows_lock);
 
         memcpy(r_addr, &addr, MAC_SIZE);
 
-        if (eth_llc_ipcp_sap_alloc(r_addr, ssap, hash, cube) < 0) {
-                pthread_rwlock_wrlock(&eth_llc_data.flows_lock);
-                bmp_release(eth_llc_data.saps, eth_llc_data.fd_to_ef[fd].sap);
-                eth_llc_data.fd_to_ef[fd].sap = -1;
-                eth_llc_data.ef_to_fd[ssap]   = -1;
-                pthread_rwlock_unlock(&eth_llc_data.flows_lock);
+        if (eth_ipcp_alloc(r_addr,
+#if defined(BUILD_ETH_DIX)
+                           fd,
+#elif defined(BUILD_ETH_LLC)
+                           ssap,
+#endif
+                           hash, cube) < 0) {
+#ifdef BUILD_ETH_LLC
+                pthread_rwlock_wrlock(&eth_data.flows_lock);
+                bmp_release(eth_data.saps, eth_data.fd_to_ef[fd].sap);
+                eth_data.fd_to_ef[fd].sap = -1;
+                eth_data.ef_to_fd[ssap]   = -1;
+                pthread_rwlock_unlock(&eth_data.flows_lock);
+#endif
                 return -1;
         }
 
-        fset_add(eth_llc_data.np1_flows, fd);
-
+        fset_add(eth_data.np1_flows, fd);
+#if defined(BUILD_ETH_DIX)
+        log_dbg("Pending flow with fd %d.", fd);
+#elif defined(BUILD_ETH_LLC)
         log_dbg("Pending flow with fd %d on SAP %d.", fd, ssap);
-
+#endif
         return 0;
 }
 
-static int eth_llc_ipcp_flow_alloc_resp(int fd,
-                                        int response)
+static int eth_ipcp_flow_alloc_resp(int fd,
+                                    int response)
 {
         struct timespec ts    = {0, ALLOC_TIMEO * MILLION};
         struct timespec abstime;
-        uint8_t         ssap  = 0;
-        uint8_t         r_sap = 0;
+#if defined(BUILD_ETH_DIX)
+        uint16_t        r_eid;
+#elif defined(BUILD_ETH_LLC)
+        uint8_t         ssap;
+        uint8_t         r_sap;
+#endif
         uint8_t         r_addr[MAC_SIZE];
 
         clock_gettime(PTHREAD_COND_CLOCK, &abstime);
@@ -1292,56 +1488,71 @@ static int eth_llc_ipcp_flow_alloc_resp(int fd,
 
         pthread_mutex_unlock(&ipcpi.alloc_lock);
 
-        pthread_rwlock_wrlock(&eth_llc_data.flows_lock);
-
-        ssap = bmp_allocate(eth_llc_data.saps);
-        if (!bmp_is_id_valid(eth_llc_data.saps, ssap)) {
-                pthread_rwlock_unlock(&eth_llc_data.flows_lock);
+        pthread_rwlock_wrlock(&eth_data.flows_lock);
+#if defined(BUILD_ETH_DIX)
+        r_eid = eth_data.fd_to_ef[fd].r_eid;
+#elif defined(BUILD_ETH_LLC)
+        ssap = bmp_allocate(eth_data.saps);
+        if (!bmp_is_id_valid(eth_data.saps, ssap)) {
+                pthread_rwlock_unlock(&eth_data.flows_lock);
                 return -1;
         }
 
-        eth_llc_data.fd_to_ef[fd].sap = ssap;
-        memcpy(r_addr, eth_llc_data.fd_to_ef[fd].r_addr, MAC_SIZE);
-        r_sap = eth_llc_data.fd_to_ef[fd].r_sap;
-        eth_llc_data.ef_to_fd[ssap] = fd;
+        eth_data.fd_to_ef[fd].sap = ssap;
+        r_sap = eth_data.fd_to_ef[fd].r_sap;
+        eth_data.ef_to_fd[ssap] = fd;
+#endif
+        memcpy(r_addr, eth_data.fd_to_ef[fd].r_addr, MAC_SIZE);
 
-        pthread_rwlock_unlock(&eth_llc_data.flows_lock);
+        pthread_rwlock_unlock(&eth_data.flows_lock);
 
-        if (eth_llc_ipcp_sap_alloc_resp(r_addr, ssap, r_sap, response) < 0) {
-                pthread_rwlock_wrlock(&eth_llc_data.flows_lock);
-                bmp_release(eth_llc_data.saps, eth_llc_data.fd_to_ef[fd].sap);
-                pthread_rwlock_unlock(&eth_llc_data.flows_lock);
+        if (eth_ipcp_alloc_resp(r_addr,
+#if defined(BUILD_ETH_DIX)
+                                fd, r_eid,
+#elif defined(BUILD_ETH_LLC)
+                                ssap, r_sap,
+#endif
+                                response) < 0) {
+#ifdef BUILD_ETH_LLC
+                pthread_rwlock_wrlock(&eth_data.flows_lock);
+                bmp_release(eth_data.saps, eth_data.fd_to_ef[fd].sap);
+                pthread_rwlock_unlock(&eth_data.flows_lock);
+#endif
                 return -1;
         }
 
-        fset_add(eth_llc_data.np1_flows, fd);
-
+        fset_add(eth_data.np1_flows, fd);
+#if defined(BUILD_ETH_DIX)
+        log_dbg("Accepted flow, fd %d.", fd);
+#elif defined(BUILD_ETH_LLC)
         log_dbg("Accepted flow, fd %d, SAP %d.", fd, (uint8_t)ssap);
-
+#endif
         return 0;
 }
 
-static int eth_llc_ipcp_flow_dealloc(int fd)
+static int eth_ipcp_flow_dealloc(int fd)
 {
+#ifdef BUILD_ETH_LLC
         uint8_t sap;
-        uint8_t addr[MAC_SIZE];
-
+#endif
         ipcp_flow_fini(fd);
 
-        pthread_rwlock_wrlock(&eth_llc_data.flows_lock);
+        pthread_rwlock_wrlock(&eth_data.flows_lock);
 
-        fset_del(eth_llc_data.np1_flows, fd);
+        fset_del(eth_data.np1_flows, fd);
 
-        sap = eth_llc_data.fd_to_ef[fd].sap;
-        memcpy(addr, eth_llc_data.fd_to_ef[fd].r_addr, MAC_SIZE);
-        bmp_release(eth_llc_data.saps, sap);
-        eth_llc_data.fd_to_ef[fd].sap = -1;
-        eth_llc_data.fd_to_ef[fd].r_sap = -1;
-        memset(&eth_llc_data.fd_to_ef[fd].r_addr, 0, MAC_SIZE);
-
-        eth_llc_data.ef_to_fd[sap] = -1;
+#if defined(BUILD_ETH_DIX)
+        eth_data.fd_to_ef[fd].r_eid = -1;
+#elif defined BUILD_ETH_LLC
+        sap = eth_data.fd_to_ef[fd].sap;
+        bmp_release(eth_data.saps, sap);
+        eth_data.fd_to_ef[fd].sap = -1;
+        eth_data.fd_to_ef[fd].r_sap = -1;
+        eth_data.ef_to_fd[sap] = -1;
+#endif
+        memset(&eth_data.fd_to_ef[fd].r_addr, 0, MAC_SIZE);
 
-        pthread_rwlock_unlock(&eth_llc_data.flows_lock);
+        pthread_rwlock_unlock(&eth_data.flows_lock);
 
         flow_dealloc(fd);
 
@@ -1350,27 +1561,31 @@ static int eth_llc_ipcp_flow_dealloc(int fd)
         return 0;
 }
 
-static struct ipcp_ops eth_llc_ops = {
-        .ipcp_bootstrap       = eth_llc_ipcp_bootstrap,
+static struct ipcp_ops eth_ops = {
+        .ipcp_bootstrap       = eth_ipcp_bootstrap,
         .ipcp_enroll          = NULL,
         .ipcp_connect         = NULL,
         .ipcp_disconnect      = NULL,
-        .ipcp_reg             = eth_llc_ipcp_reg,
-        .ipcp_unreg           = eth_llc_ipcp_unreg,
-        .ipcp_query           = eth_llc_ipcp_query,
-        .ipcp_flow_alloc      = eth_llc_ipcp_flow_alloc,
-        .ipcp_flow_alloc_resp = eth_llc_ipcp_flow_alloc_resp,
-        .ipcp_flow_dealloc    = eth_llc_ipcp_flow_dealloc
+        .ipcp_reg             = eth_ipcp_reg,
+        .ipcp_unreg           = eth_ipcp_unreg,
+        .ipcp_query           = eth_ipcp_query,
+        .ipcp_flow_alloc      = eth_ipcp_flow_alloc,
+        .ipcp_flow_alloc_resp = eth_ipcp_flow_alloc_resp,
+        .ipcp_flow_dealloc    = eth_ipcp_flow_dealloc
 };
 
 int main(int    argc,
          char * argv[])
 {
-        if (ipcp_init(argc, argv, &eth_llc_ops) < 0)
+        if (ipcp_init(argc, argv, &eth_ops) < 0)
                 goto fail_init;
 
-        if (eth_llc_data_init() < 0) {
+        if (eth_data_init() < 0) {
+#if defined(BUILD_ETH_DIX)
                 log_err("Failed to init eth-llc data.");
+#elif defined(BUILD_ETH_LLC)
+                log_err("Failed to init eth-dix data.");
+#endif
                 goto fail_data_init;
         }
 
@@ -1388,21 +1603,21 @@ int main(int    argc,
         ipcp_shutdown();
 
         if (ipcp_get_state() == IPCP_SHUTDOWN) {
-                pthread_cancel(eth_llc_data.sdu_writer);
-                pthread_cancel(eth_llc_data.sdu_reader);
-                pthread_cancel(eth_llc_data.mgmt_handler);
+                pthread_cancel(eth_data.sdu_writer);
+                pthread_cancel(eth_data.sdu_reader);
+                pthread_cancel(eth_data.mgmt_handler);
 #ifdef __linux__
-                pthread_cancel(eth_llc_data.if_monitor);
+                pthread_cancel(eth_data.if_monitor);
 #endif
-                pthread_join(eth_llc_data.sdu_writer, NULL);
-                pthread_join(eth_llc_data.sdu_reader, NULL);
-                pthread_join(eth_llc_data.mgmt_handler, NULL);
+                pthread_join(eth_data.sdu_writer, NULL);
+                pthread_join(eth_data.sdu_reader, NULL);
+                pthread_join(eth_data.mgmt_handler, NULL);
 #ifdef __linux__
-                pthread_join(eth_llc_data.if_monitor, NULL);
+                pthread_join(eth_data.if_monitor, NULL);
 #endif
         }
 
-        eth_llc_data_fini();
+        eth_data_fini();
 
         ipcp_fini();
 
@@ -1411,7 +1626,7 @@ int main(int    argc,
  fail_create_r:
         ipcp_shutdown();
  fail_boot:
-        eth_llc_data_fini();
+        eth_data_fini();
  fail_data_init:
         ipcp_fini();
  fail_init:
diff --git a/src/ipcpd/eth/llc.c b/src/ipcpd/eth/llc.c
new file mode 100644
index 0000000..fa33218
--- /dev/null
+++ b/src/ipcpd/eth/llc.c
@@ -0,0 +1,26 @@
+/*
+ * Ouroboros - Copyright (C) 2016 - 2018
+ *
+ * IPC processes over Ethernet - LLC
+ *
+ *    Dimitri Staessens <dimitri.staessens@xxxxxxxx>
+ *    Sander Vrijders   <sander.vrijders@xxxxxxxx>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., http://www.fsf.org/about/contact/.
+ */
+
+#define BUILD_ETH_LLC
+#define OUROBOROS_PREFIX "ipcpd/eth-llc"
+
+#include "eth.c"
diff --git a/src/ipcpd/ipcp.c b/src/ipcpd/ipcp.c
index 4900ec0..b0ce87c 100644
--- a/src/ipcpd/ipcp.c
+++ b/src/ipcpd/ipcp.c
@@ -246,7 +246,12 @@ static void * mainloop(void * o)
                         }
 
                         if (conf_msg->ipcp_type == IPCP_ETH_LLC)
-                                conf.if_name        = conf_msg->if_name;
+                                conf.dev = conf_msg->dev;
+
+                        if (conf_msg->ipcp_type == IPCP_ETH_DIX) {
+                                conf.dev = conf_msg->dev;
+                                conf.ethertype = conf_msg->ethertype;
+                        }
 
                         if (conf_msg->ipcp_type == IPCP_UDP) {
                                 conf.ip_addr  = conf_msg->ip_addr;
diff --git a/src/irmd/config.h.in b/src/irmd/config.h.in
index 923a6ef..0ac961f 100644
--- a/src/irmd/config.h.in
+++ b/src/irmd/config.h.in
@@ -22,6 +22,7 @@
 
 #define IPCP_UDP_EXEC           "@IPCP_UDP_TARGET@"
 #define IPCP_ETH_LLC_EXEC       "@IPCP_ETH_LLC_TARGET@"
+#define IPCP_ETH_DIX_EXEC       "@IPCP_ETH_DIX_TARGET@"
 #define IPCP_NORMAL_EXEC        "@IPCP_NORMAL_TARGET@"
 #define IPCP_LOCAL_EXEC         "@IPCP_LOCAL_TARGET@"
 #define IPCP_RAPTOR_EXEC        "@IPCP_RAPTOR_TARGET@"
diff --git a/src/irmd/ipcp.c b/src/irmd/ipcp.c
index f90ba25..efb5fbf 100644
--- a/src/irmd/ipcp.c
+++ b/src/irmd/ipcp.c
@@ -146,6 +146,9 @@ pid_t ipcp_create(const char *   name,
         case IPCP_ETH_LLC:
                 exec_name = IPCP_ETH_LLC_EXEC;
                 break;
+        case IPCP_ETH_DIX:
+                exec_name = IPCP_ETH_DIX_EXEC;
+                break;
         case IPCP_LOCAL:
                 exec_name = IPCP_LOCAL_EXEC;
                 break;
diff --git a/src/lib/ipcp_config.proto b/src/lib/ipcp_config.proto
index 3e656d4..44391f3 100644
--- a/src/lib/ipcp_config.proto
+++ b/src/lib/ipcp_config.proto
@@ -40,8 +40,10 @@ message ipcp_config_msg {
         // Config for UDP
         optional uint32 ip_addr            =  9;
         optional uint32 dns_addr           = 10;
-        // Config for the Ethernet LLC
-        optional string if_name            = 11;
+        // Config for the Ethernet
+        optional string dev                = 11;
+        // Config for DIX Ethernet
+        optional uint32 ethertype          = 12;
 }
 
 enum enroll_code {
diff --git a/src/lib/irm.c b/src/lib/irm.c
index 66b5c84..c12ab89 100644
--- a/src/lib/irm.c
+++ b/src/lib/irm.c
@@ -139,7 +139,12 @@ int irm_bootstrap_ipcp(pid_t                      pid,
         case IPCP_RAPTOR:
                 break;
         case IPCP_ETH_LLC:
-                config.if_name = conf->if_name;
+                config.dev = conf->dev;
+                break;
+        case IPCP_ETH_DIX:
+                config.dev = conf->dev;
+                config.has_ethertype = true;
+                config.ethertype = conf->ethertype;
                 break;
         default:
                 return -EIPCPTYPE;
diff --git a/src/tools/irm/irm_ipcp_bootstrap.c 
b/src/tools/irm/irm_ipcp_bootstrap.c
index 986c45e..da8914d 100644
--- a/src/tools/irm/irm_ipcp_bootstrap.c
+++ b/src/tools/irm/irm_ipcp_bootstrap.c
@@ -51,6 +51,7 @@
 #define NORMAL                 "normal"
 #define UDP                    "udp"
 #define ETH_LLC                "eth-llc"
+#define ETH_DIX                "eth-dix"
 #define LOCAL                  "local"
 #define RAPTOR                 "raptor"
 
@@ -74,6 +75,7 @@
 #define SIMPLE_PFF             "simple"
 #define ALTERNATE_PFF          "alternate"
 
+#define DEFAULT_ETHERTYPE      0xA000
 static void usage(void)
 {
         /* FIXME: Add ipcp_config stuff. */
@@ -82,7 +84,7 @@ static void usage(void)
                "                layer <layer name>\n"
                "                type [TYPE]\n"
                "where TYPE = {" NORMAL " " LOCAL " "
-               UDP " " ETH_LLC " " RAPTOR "},\n\n"
+               UDP " " ETH_LLC " " ETH_DIX " " RAPTOR "},\n\n"
                "if TYPE == " NORMAL "\n"
                "                [addr <address size> (default: %d)]\n"
                "                [eid <eid size> (default: %d)]\n"
@@ -103,7 +105,13 @@ static void usage(void)
                "                [dns <DDNS IP address in dotted notation>"
                " (default: none)]\n\n"
                "if TYPE == " ETH_LLC "\n"
-               "                if_name <interface name>\n"
+               "                dev <interface name>\n"
+               "                [hash [ALGORITHM] (default: %s)]\n"
+               "where ALGORITHM = {" SHA3_224 " " SHA3_256 " "
+               SHA3_384 " " SHA3_512 "}\n\n"
+               "if TYPE == " ETH_DIX "\n"
+               "                dev <interface name>\n"
+               "                [ethertype <ethertype> (default: 0x%4X)]\n"
                "                [hash [ALGORITHM] (default: %s)]\n"
                "where ALGORITHM = {" SHA3_224 " " SHA3_256 " "
                SHA3_384 " " SHA3_512 "}\n\n"
@@ -117,7 +125,7 @@ static void usage(void)
                SHA3_384 " " SHA3_512 "}\n\n",
                DEFAULT_ADDR_SIZE, DEFAULT_EID_SIZE, DEFAULT_TTL,
                FLAT_RANDOM_ADDR_AUTH, LINK_STATE_ROUTING, SIMPLE_PFF,
-               SHA3_256, SHA3_256, SHA3_256, SHA3_256);
+               SHA3_256, SHA3_256, 0xA000, SHA3_256, SHA3_256, SHA3_256);
 }
 
 int do_bootstrap_ipcp(int     argc,
@@ -137,7 +145,8 @@ int do_bootstrap_ipcp(int     argc,
         uint32_t           dns_addr       = DEFAULT_DDNS;
         char *             ipcp_type      = NULL;
         char *             layer_name     = NULL;
-        char *             if_name        = NULL;
+        char *             dev            = NULL;
+        uint16_t           ethertype      = DEFAULT_ETHERTYPE;
         pid_t *            pids           = NULL;
         ssize_t            len            = 0;
         int                i              = 0;
@@ -169,8 +178,14 @@ int do_bootstrap_ipcp(int     argc,
                 } else if (matches(*argv, "dns") == 0) {
                         if (inet_pton(AF_INET, *(argv + 1), &dns_addr) != 1)
                                 goto unknown_param;
-                } else if (matches(*argv, "if_name") == 0) {
-                        if_name = *(argv + 1);
+                } else if (matches(*argv, "device") == 0) {
+                        dev = *(argv + 1);
+                } else if (matches(*argv, "ethertype") == 0) {
+                        /* NOTE: We might do some checks on this. */
+                        if (matches(*(argv + 1), "0x") == 0)
+                                ethertype = strtol(*(argv + 1), NULL, 0);
+                        else
+                                ethertype = strtol(*(argv + 1), NULL, 16);
                 } else if (matches(*argv, "addr") == 0) {
                         addr_size = atoi(*(argv + 1));
                 } else if (matches(*argv, "eid") == 0) {
@@ -240,11 +255,19 @@ int do_bootstrap_ipcp(int     argc,
                 conf.type = IPCP_RAPTOR;
         } else if (strcmp(ipcp_type, ETH_LLC) == 0) {
                 conf.type = IPCP_ETH_LLC;
-                if (if_name == NULL) {
+                if (dev == NULL) {
+                        usage();
+                        return -1;
+                }
+                conf.dev = dev;
+        } else if (strcmp(ipcp_type, ETH_DIX) == 0) {
+                conf.type = IPCP_ETH_DIX;
+                if (dev == NULL) {
                         usage();
                         return -1;
                 }
-                conf.if_name = if_name;
+                conf.dev = dev;
+                conf.ethertype = ethertype;
         } else {
                 usage();
                 return -1;
-- 
2.16.2


Other related posts:

  • » [PATCH] ipcpd: Add an IPCP over DIX Ethernet - Dimitri Staessens