libnet: implemented adding/removing hardware filters from solarflare card
authorRoni Häcki <roni.haecki@inf.ethz.ch>
Mon, 10 Apr 2017 12:39:55 +0000 (14:39 +0200)
committerRoni Häcki <roni.haecki@inf.ethz.ch>
Mon, 10 Apr 2017 12:39:55 +0000 (14:39 +0200)
Signed-off-by: Roni Häcki <roni.haecki@inf.ethz.ch>

errors/errno.fugu
if/Hakefile
if/net_filter.if [new file with mode: 0644]
lib/net/Hakefile
lib/net/include/net/net_filter.h [new file with mode: 0644]
lib/net/net.c
lib/net/net_filter.c [new file with mode: 0644]
lib/net/test/udp_echo.c
platforms/Hakefile
usr/drivers/solarflare/Hakefile
usr/drivers/solarflare/sfn5122f_cdriver.c

index b0e9a8f..e99e5ce 100755 (executable)
@@ -748,6 +748,11 @@ errors filter PORT_ERR_ {
 };
 
 
+//errors in Filter management
+errors filter NET_FILTER_ERR_ {
+    failure NOT_FOUND           "Filter not found or not installed",
+    failure ALREADY_EXISTS      "Filter already installed",
+};
 
 
 //errors in Filter management
index d674a4f..b6fe4a1 100644 (file)
@@ -92,7 +92,8 @@
                "xomp_gateway",
                "sfn5122f",
                "sfn5122f_devif",
-               "descq"
+               "descq",
+               "net_filter"
            ],
              arch <- allArchitectures
 ] ++
diff --git a/if/net_filter.if b/if/net_filter.if
new file mode 100644 (file)
index 0000000..631be9b
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2017, ETH Zurich.
+ * All rights reserved.
+ *
+ * This file is distributed under the terms in the attached LICENSE file.
+ * If you do not find this file, copies can be found by writing to:
+ * ETH Zurich D-INFK, Universitaetsstrasse 6, CH-8092 Zurich. Attn: Systems Group.
+ */
+
+interface net_filter "Network Filter Interface" {
+    typedef enum {PORT_TCP, PORT_UDP, MAC} filter_type;
+
+    rpc install_filter_ip(in filter_type type,
+                          in uint64 qid,
+                          in uint32 src_ip,
+                          in uint32 dst_ip,
+                          in uint16 src_port,
+                          in uint16 dst_port,
+                          out uint64 filter_id);
+
+    rpc install_filter_mac(in uint64 dst_mac,
+                           in uint64 vlan_id,
+                           out errval err,
+                           out uint64 filter_id);
+
+    rpc remove_filter(in filter_type type,
+                      in uint64 filter_id,
+                      out errval err);
+
+};
+
index ac94569..bd0e192 100644 (file)
 
 [ build library { 
     target       = "net",
-    cFiles       = [ "net.c", "netbufs.c",  "netif.c", "pbuf.c", "dhcp.c" ],
+    cFiles       = [ "net.c", "netbufs.c",  "netif.c", "pbuf.c", "dhcp.c",
+                     "net_filter.c" ],
     addIncludes  = [ "include", "/lib/lwip-2.0.2/src/include/" ],
+    flounderBindings = [ "net_filter"],
+    flounderExtraBindings = [ ("net_filter", ["rpcclient"])],
+    flounderDefs = [ "net_filter" ],
+    flounderExtraDefs = [ ("net_filter",["rpcclient"]) ],
     addLibraries = libDeps [ "lwip2", "devif", "devif_backend_idc",
                              "devif_backend_solarflare", "devif_backend_e10k",
                              "devif_backend_loopback",
diff --git a/lib/net/include/net/net_filter.h b/lib/net/include/net/net_filter.h
new file mode 100644 (file)
index 0000000..27d75cd
--- /dev/null
@@ -0,0 +1,48 @@
+/**
+ * @brief 
+ *  net_filter.h
+ *  Install filters (mostly HW)
+ */
+
+/*
+ * Copyright (c) 2017, ETH Zurich.
+ * All rights reserved.
+ *
+ * This file is distributed under the terms in the attached LICENSE file.
+ * If you do not find this file, copies can be found by writing to:
+ * ETH Zurich D-INFK, Universitaetsstrasse 6, CH-8092 Zurich. Attn: Systems Group.
+ */
+
+#ifndef LIB_NET_INCLUDE_NETWORKING_FILTER_H_
+#define LIB_NET_INCLUDE_NETWORKING_FILTER_H_
+
+#include <barrelfish/barrelfish.h>
+
+#define NET_FILTER_TCP 0
+#define NET_FILTER_UPD 1
+#define NET_FILTER_MAC 2
+
+struct net_filter_ip {
+    uint64_t qid;
+    uint32_t ip_src;
+    uint32_t ip_dst;          
+    uint16_t port_src;
+    uint16_t port_dst;
+    uint8_t type;
+};
+
+struct net_filter_mac {
+    uint8_t type;
+    uint64_t vlan_id;
+    uint64_t mac;
+};
+
+errval_t net_filter_init(const char* cardname);
+
+errval_t net_filter_ip_install(struct net_filter_ip* filt);
+errval_t net_filter_mac_install(struct net_filter_mac* filt);
+
+errval_t net_filter_ip_remove(struct net_filter_ip* filt);
+errval_t net_filter_mac_remove(struct net_filter_mac* filt);
+
+#endif /* LIB_NET_INCLUDE_NETWORKING_FILTER_H_ */
index 254aa7e..786f1eb 100644 (file)
 #include "lwip/dhcp.h"
 #include "lwip/prot/ethernet.h"
 
+#include <barrelfish/barrelfish.h>
 #include <barrelfish/deferred.h>
 
-
+#include <net/net_filter.h>
 #include <net_interfaces/flags.h>
 #include "networking_internal.h"
 
@@ -238,6 +239,16 @@ static errval_t networking_init_with_queue_st(struct net_state *st,struct devq *
     }
 
 
+    NETDEBUG("initializing hw filter...\n");
+
+    err = net_filter_init(st->cardname);
+    if (err_is_fail(err)) {
+        USER_PANIC("Init filter infrastructure failed: %s \n", err_getstring(err));
+    }
+
+    NETDEBUG("setting default netif...\n");
+   // netif_set_default(&st->netif);
+
     /* create buffers and add them to the interface*/
     err = net_buf_pool_alloc(st->queue, NETWORKING_BUFFER_COUNT,
                              NETWORKING_BUFFER_SIZE, &st->pool);
@@ -259,7 +270,6 @@ static errval_t networking_init_with_queue_st(struct net_state *st,struct devq *
         }
     }
 
-
     if (flags & NET_FLAGS_DO_DHCP) {
         err = dhcpd_start(flags);
         if (err_is_fail(err)) {
diff --git a/lib/net/net_filter.c b/lib/net/net_filter.c
new file mode 100644 (file)
index 0000000..d1781e5
--- /dev/null
@@ -0,0 +1,326 @@
+/*
+ * Copyright (c) 2017, ETH Zurich.
+ * All rights reserved.
+ *
+ * This file is distributed under the terms in the attached LICENSE file.
+ * If you do not find this file, copies can be found by writing to:
+ * ETH Zurich D-INFK, Universitaetsstrasse 6, CH-8092 Zurich. Attn: Systems Group.
+ */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <barrelfish/barrelfish.h>
+#include <barrelfish/nameservice_client.h>
+#include <if/net_filter_defs.h>
+#include <if/net_filter_rpcclient_defs.h>
+
+#include "include/net/net_filter.h"
+
+#include "networking_internal.h"
+#include "debug.h"
+
+#define MAX_NAME 128
+
+#define NETDEBUG_SUBSYSTEM "filter"
+
+struct net_filter_ele {
+    union {
+        struct net_filter_ip ip;
+        struct net_filter_mac mac;
+    } filter;
+    uint64_t filter_id;
+    struct net_filter_ele* next;
+    struct net_filter_ele* prev;
+};
+
+struct filter_list {
+    struct net_filter_ele* start;
+    uint64_t num_ele;  
+};
+
+struct net_filter_state {
+    struct filter_list filters_ip;
+    struct filter_list filters_mac;
+    struct net_filter_binding* b;
+    volatile bool bound;
+};
+
+
+/******************************************************************************
+ * Global state
+ ******************************************************************************/
+
+static struct net_filter_state filter_state;
+
+/******************************************************************************
+ * Connection setup
+ ******************************************************************************/
+
+// Callback for bind
+static void bind_cb(void *st, errval_t err, struct net_filter_binding *b)
+{
+    assert(err_is_ok(err));
+
+    NETDEBUG("Sucessfully connected to management interface\n");
+
+    filter_state.b = b;
+    net_filter_rpc_client_init(filter_state.b);
+    filter_state.bound = true;
+}
+
+
+/** Open connection to management interface */
+static errval_t connect_to_net_filter(const char *dev_name)
+{
+    errval_t r;
+    iref_t iref;
+    const char* prefix = "net_filter_";
+    char name[strlen(dev_name) + strlen(prefix) + 1];
+   
+    // Build label for management service
+    sprintf(name, "%s%s", prefix, dev_name);
+
+    NETDEBUG("Name lookup\n");
+    // Connect to service
+    r = nameservice_blocking_lookup(name, &iref);
+    if (err_is_fail(r)) {
+        return r;
+    }
+
+    NETDEBUG("Binding\n");
+    r = net_filter_bind(iref, bind_cb, &filter_state, get_default_waitset(),
+            IDC_BIND_FLAGS_DEFAULT);
+    if (err_is_fail(r)) {
+        return r;
+    }
+
+    NETDEBUG("Waiting to bind\n");
+    while(filter_state.bound == false) {
+        event_dispatch(get_default_waitset());
+    }
+    
+    NETDEBUG("finished connecting\n");
+    return SYS_ERR_OK;
+}
+
+/******************************************************************************
+ * Helper functions
+ ******************************************************************************/
+
+static bool filter_cmp_ip(struct net_filter_ip* f1, struct net_filter_ip* f2)
+{
+    if (f1->ip_src == f2->ip_src &&
+        f1->ip_dst == f2->ip_dst &&
+        f1->port_src == f2->port_src &&
+        f1->port_dst == f2->port_dst &&
+        f1->qid == f2->qid &&
+        f1->type == f2->type) {
+        return true;
+    }
+    return false;
+}
+
+/*
+static bool filter_cmp_mac(struct net_filter_mac* f1, struct net_filter_mac* f2)
+{
+    if (f1->vlan_id == f2->vlan_id &&
+        f1->mac == f2->mac &&
+        f1->type == f2->type) {
+        return true;
+    }
+    return false;
+}
+*/
+/*
+static bool is_reachable(struct net_filter_ip* filt)
+{
+    struct net_filter_ele* cur = filter_state.filters_ip.start;
+    
+    while(cur != NULL) {
+        printf("reachable: port_dst: %"PRIu16" %"PRIu16" \n", cur->filter.ip.port_dst, filt->port_dst);
+        if (filter_cmp_ip(&cur->filter.ip, filt)) {
+            return true;
+        }
+        cur = cur->next;
+    }
+    return false;
+}
+*/
+/******************************************************************************
+ * Library function implementation
+ ******************************************************************************/
+
+/**
+ * @brief initalized network filtering. Sets up connection to drivers
+ *        which support hardware filtering
+ *
+ * @param cardname  returns the card name to be used
+ *
+ * @return SYS_ERR_OK on success, error on failure
+ */
+errval_t net_filter_init(const char* cardname)
+{   
+    errval_t err;
+
+    filter_state.filters_ip.start = NULL;
+    filter_state.filters_ip.num_ele = 0;
+    filter_state.filters_mac.start = NULL;
+    filter_state.filters_mac.num_ele = 0;
+
+    err = connect_to_net_filter(cardname);
+    return err;
+}
+
+
+/**
+ * @brief Installs an L3/L4 filter in the hardware filter 
+ *        tables
+ *
+ * @param filt  filter struct
+ *
+ * @return SYS_ERR_OK on success, error on failure
+ */
+errval_t net_filter_ip_install(struct net_filter_ip* filt)
+{
+
+    assert(filter_state.bound);
+    errval_t err;
+    uint64_t filter_id;
+
+    struct net_filter_ele* cur = filter_state.filters_ip.start;
+    struct net_filter_ele* prev = NULL;
+
+    /* go through linked list and find last element 
+     (and check if filter is already installed) */
+    if (cur == NULL) {
+        filter_state.filters_ip.start = malloc(sizeof(struct net_filter_ele));
+        cur = filter_state.filters_ip.start;
+    } else {
+        while(cur->next != NULL) {
+            if (filter_cmp_ip(&cur->filter.ip, filt)) {
+                return NET_FILTER_ERR_ALREADY_EXISTS;
+            }
+            prev = cur;
+            cur = cur->next;
+        }
+
+        if (filter_cmp_ip(&cur->filter.ip, filt)) {
+            return NET_FILTER_ERR_ALREADY_EXISTS;
+        }
+
+        cur->next = malloc(sizeof(struct net_filter_ele));
+        cur = cur->next;
+    }
+
+    cur->filter.ip.ip_src = filt->ip_src;
+    cur->filter.ip.ip_dst = filt->ip_dst;
+    cur->filter.ip.port_src = filt->port_src;
+    cur->filter.ip.port_dst = filt->port_dst;
+    cur->filter.ip.qid = filt->qid;
+    cur->filter.ip.type = filt->type;
+    cur->next = NULL;
+    cur->prev = prev;    
+
+    filter_state.filters_ip.num_ele++;
+
+    err = filter_state.b->rpc_tx_vtbl.install_filter_ip(filter_state.b,
+                                                 filt->type,
+                                                 filt->qid,
+                                                 filt->ip_src,
+                                                 filt->ip_dst,
+                                                 filt->port_src,
+                                                 filt->port_dst,
+                                                 &filter_id);
+    if (err_is_fail(err)) {
+        free(cur);
+        return err;
+    }
+
+    cur->filter_id = filter_id;
+    return SYS_ERR_OK;
+}
+
+
+/**
+ * @brief Removes an L3/L4 filter in the hardware filter 
+ *        tables
+ *
+ * @param filt  filter struct
+ *
+ * @return SYS_ERR_OK on success, error on failure
+ */
+errval_t net_filter_ip_remove(struct net_filter_ip* filt)
+{
+
+    assert(filter_state.bound);
+    errval_t err, err2;
+    uint64_t filter_id = (uint64_t)-1;
+
+    struct net_filter_ele* cur = filter_state.filters_ip.start;
+    struct net_filter_ele* prev = NULL;
+
+
+    // no entries
+    if (cur == NULL) {
+        return NET_FILTER_ERR_NOT_FOUND;
+    }
+
+    // Multiple entries
+    while(cur != NULL) {
+        if (filter_cmp_ip(&cur->filter.ip, filt)) {
+            filter_id = cur->filter_id;
+            printf("Break \n");
+            break;
+        }
+        prev = cur;
+        cur = cur->next;
+    }
+
+   
+    if (filter_id == (uint64_t) -1) {
+        return NET_FILTER_ERR_NOT_FOUND;
+    }
+
+    err = filter_state.b->rpc_tx_vtbl.remove_filter(filter_state.b,
+                                                    filt->type,
+                                                    filter_id,
+                                                    &err2);
+    if (err_is_fail(err) || err_is_fail(err2)) {
+        return err_is_fail(err) ? err: err2;
+    }
+
+    // remove from queue
+    if (prev != NULL) { // check if first
+        prev->next = cur->next;
+        if (cur->next != NULL) { // check if last
+            cur->next->prev = prev;
+            printf("cur->next->prev id %d \n", cur->next->prev->filter.ip.port_dst);
+            printf("prev->next id %d \n", prev->next->filter.ip.port_dst);
+        } 
+    } else {
+        printf("start id %d \n", filter_state.filters_ip.start->filter.ip.port_dst);
+        filter_state.filters_ip.start = cur->next;
+    }
+    
+
+    free(cur);
+
+    filter_state.filters_ip.num_ele--;
+
+    return SYS_ERR_OK;
+}
+
+errval_t net_filter_mac_install(struct net_filter_mac* filt)
+{
+   USER_PANIC("NYI \n");
+}
+
+
+errval_t net_filter_mac_remove(struct net_filter_mac* filt)
+{
+   USER_PANIC("NYI \n");
+}
+
index 0124822..1cca341 100644 (file)
@@ -18,6 +18,7 @@
 #include <lwip/udp.h>
 #include <lwip/pbuf.h>
 #include <net/net.h>
+#include <net/net_filter.h>
 
 #define UDP_ECHOSERVER_PORT 7
 
@@ -70,6 +71,20 @@ int main(int argc, char *argv[])
         return(r);
     }
 
+    struct net_filter_ip ip;
+    ip.qid = 1;
+    ip.ip_src = 0;
+    // TODO 10.110.4.39 get this from somewhere
+    ip.ip_dst = 0x2704710A;
+    ip.port_dst = 7;
+    ip.port_src = 0;
+    ip.type = NET_FILTER_UPD;
+
+    err = net_filter_ip_install(&ip);    
+    if (err_is_fail(err)) {
+        USER_PANIC("Adding filter failed %s \n", err_getstring(err));
+    }
+
     debug_printf("UDP ECHO bound to UDP port %u.\n", UDP_ECHOSERVER_PORT);
 
     udp_recv(pcb, echo_recv_handler,  0);
index fdf4a10..8ea5392 100644 (file)
@@ -216,6 +216,7 @@ let bin_rcce_lu = [ "/sbin/" ++ f | f <- [
                            "rtl8029",
                            "serial_pc16550d",
                            "sfxge",
+                           "sfn5122f",
                            "slideshow",
                            "sshd",
                            "vbe",
@@ -225,7 +226,7 @@ let bin_rcce_lu = [ "/sbin/" ++ f | f <- [
                            "vnode_map_test",
                            "webserver",
                            "xeon_phi",
-                           "xeon_phi_mgr"
+                           "xeon_phi_mgr",
                            ]] ++ modules_common
 
     -- the following are broken in the newidc system
index 0f5ae4e..dc45321 100644 (file)
   build application { target = "sfn5122f",
                       cFiles = [ "sfn5122f_cdriver.c", "mcdi_rpc.c", "helper.c", 
                                  "buffer_tbl.c", "sfn5122f_qdriver.c"],
-                      flounderBindings = [ "sfn5122f", "net_ARP", "sfn5122f_devif"],
-                      flounderExtraBindings = [ ("sfn5122f_devif", ["rpcclient"]) ],
-                      flounderDefs = [ "sfn5122f", "sfn5122f_devif" ],
+                      flounderBindings = [ "sfn5122f", "net_ARP", "sfn5122f_devif", "net_filter"],
+                      flounderExtraBindings = [ ("sfn5122f_devif", ["rpcclient"]),  
+                                                ("net_filter", ["rpcclient"])],
+                      flounderDefs = [ "sfn5122f", "sfn5122f_devif", "net_filter"],
                       flounderExtraDefs = [
                         ("net_ARP",["rpcclient"]),
-                        ("sfn5122f_devif",["rpcclient"])
+                        ("sfn5122f_devif",["rpcclient"]),
+                        ("net_filter",["rpcclient"])
                         ],
                       mackerelDevices = [ "sfn5122f"],
                       addLibraries = libDeps["netQmng", "pci", "contmng", 
index 36e8300..40b2e84 100644 (file)
@@ -22,7 +22,7 @@
 #include <barrelfish/debug.h>
 #include <if/sfn5122f_defs.h>
 #include <if/sfn5122f_devif_defs.h>
-#include <if/sfn5122f_devif_defs.h>
+#include <if/net_filter_defs.h>
 #include <if/net_ARP_defs.h>
 #include <if/net_ARP_defs.h>
 
@@ -31,6 +31,7 @@
 #include "buffer_tbl.h"
 #include "sfn5122f_qdriver.h"
 
+
 struct queue_state {
     bool enabled;
     bool userspace;
@@ -93,9 +94,8 @@ static uint32_t phy_loopback_mode = 0;
 static uint32_t wol_filter_id = 0;
 
 // ARP rpc client
-static struct net_ARP_binding *arp_binding;
-static bool net_arp_connected = false;
-static struct waitset rpc_ws;
+//static struct net_ARP_binding *arp_binding;
+//static bool net_arp_connected = false;
 
 static bool csum_offload = 1;
 // TX / RX
@@ -124,8 +124,8 @@ uint8_t rx_hash_key[40];
 uint8_t mc_hash[32];
 
 // Filters
-//static uint32_t ip = 0x2704710A;
-static uint32_t ip = 0;
+static uint32_t ip = 0x2704710A;
+//static uint32_t ip = 0;
 
 enum filter_type_ip {
     OTHER,
@@ -225,8 +225,10 @@ static void queue_hw_stop(uint16_t n);
 static void setup_interrupt(size_t *msix_index, uint8_t core, uint8_t vector);
 static void global_interrupt_handler(void* arg);
 
+/*
 static void bind_arp(struct waitset *ws);
 static errval_t arp_ip_info(void);
+*/
 /***************************************************************************/
 /* Filters */
 
@@ -235,7 +237,7 @@ static void sfn5122f_filter_port_setup(int idx, struct sfn5122f_filter_ip* filte
     sfn5122f_rx_filter_tbl_lo_t filter_lo = 0;
     sfn5122f_rx_filter_tbl_hi_t filter_hi = 0;
 
-    if (filter->type_ip == sfn5122f_PORT_UDP) {
+    if (filter->type_ip == net_filter_PORT_UDP) {
 
         // Add destination IP
         filter_hi = sfn5122f_rx_filter_tbl_hi_dest_ip_insert(filter_hi,
@@ -254,7 +256,7 @@ static void sfn5122f_filter_port_setup(int idx, struct sfn5122f_filter_ip* filte
                filter->src_ip, filter->src_port, filter->queue);
     }
 
-    if (filter->type_ip == sfn5122f_PORT_TCP) {
+    if (filter->type_ip == net_filter_PORT_TCP) {
         // Add dst IP and port
         filter_hi = sfn5122f_rx_filter_tbl_hi_dest_ip_insert(filter_hi,
                                                              filter->dst_ip);
@@ -320,6 +322,7 @@ static uint16_t filter_hash(uint32_t key)
     return tmp ^ tmp >> 9;
 }
 
+/*
 static bool filter_equals(struct sfn5122f_filter_ip* f1,
                           struct sfn5122f_filter_ip* f2)
 {
@@ -336,7 +339,7 @@ static bool filter_equals(struct sfn5122f_filter_ip* f1,
         return true;
     }
 }
-
+*/
 static uint16_t filter_increment(uint32_t key)
 {
     return key * 2 - 1;
@@ -358,9 +361,7 @@ static int ftqf_alloc(struct sfn5122f_filter_ip* f)
     while (true) {
         if (filters_rx_ip[key].enabled == false) {
             return key;
-        } else if (filter_equals(&filters_rx_ip[key], f)){
-            return key;
-        }
+        } 
         
         if (depth > 3) {
             return -1;
@@ -373,7 +374,6 @@ static int ftqf_alloc(struct sfn5122f_filter_ip* f)
     return key;
 }
 
-
 static errval_t reg_port_filter(struct sfn5122f_filter_ip* f, uint64_t* fid)
 {
     int filt_ind;
@@ -1334,6 +1334,7 @@ void cd_register_queue_memory(struct sfn5122f_binding *b,
     }
 }
 
+/*
 static errval_t idc_terminate_queue(struct sfn5122f_binding *b, uint16_t n)
 {
   DEBUG("idc_terminate_queue(q=%d) \n", n);
@@ -1359,10 +1360,7 @@ static errval_t idc_register_port_filter(struct sfn5122f_binding *b,
 {
 
     if (ip == 0) {
-        /* Get cards IP */
-        waitset_init(&rpc_ws);
-        bind_arp(&rpc_ws);
-        arp_ip_info();
+        //arp_ip_info();
         printf("IP %d \n", ip);
     }
 
@@ -1393,7 +1391,6 @@ static errval_t idc_unregister_filter(struct sfn5122f_binding *b,
     *err = LIB_ERR_NOT_IMPLEMENTED;
     return SYS_ERR_OK;
 }
-
 static struct sfn5122f_rx_vtbl rx_vtbl = {
     .request_device_info = cd_request_device_info,
     .register_queue_memory = cd_register_queue_memory,
@@ -1404,6 +1401,7 @@ static struct sfn5122f_rpc_rx_vtbl rpc_rx_vtbl = {
     .register_port_filter_call = idc_register_port_filter,
     .unregister_filter_call = idc_unregister_filter,
 };
+*/
 
 static void cd_create_queue(struct sfn5122f_devif_binding *b, struct capref frame,
                             bool user, bool interrupt, uint8_t core, uint8_t msix_vector)
@@ -1542,6 +1540,7 @@ static struct sfn5122f_devif_rx_vtbl rx_vtbl_devif = {
     .deregister_region_call = cd_deregister_region,
 };
 
+/*
 static void export_cb(void *st, errval_t err, iref_t iref)
 {
     const char *suffix = "_sfn5122fmng";
@@ -1565,7 +1564,7 @@ static errval_t connect_cb(void *st, struct sfn5122f_binding *b)
     b->rpc_rx_vtbl = rpc_rx_vtbl;
     return SYS_ERR_OK;
 }
-
+*/
 static void export_devif_cb(void *st, errval_t err, iref_t iref)
 {
     const char *suffix = "_sfn5122fmng_devif";
@@ -1590,6 +1589,87 @@ static errval_t connect_devif_cb(void *st, struct sfn5122f_devif_binding *b)
     return SYS_ERR_OK;
 }
 
+
+/****************************************************************************/
+/* Net filter interface implementation                                      */
+/****************************************************************************/
+
+
+static errval_t cb_install_filter(struct net_filter_binding *b,
+                                  net_filter_filter_type_t type,
+                                  uint64_t qid,
+                                  uint32_t src_ip,
+                                  uint32_t dst_ip,
+                                  uint16_t src_port,
+                                  uint16_t dst_port,
+                                  uint64_t* fid)
+{
+    if (ip == 0) {
+        /* Get cards IP */
+        //arp_ip_info();
+        printf("IP %d \n", ip);
+    }
+
+    struct sfn5122f_filter_ip f = {
+            .dst_port = dst_port,
+            .src_port = src_port,
+            .dst_ip = htonl(dst_ip),
+            .src_ip = htonl(src_ip),
+            .type_ip = type,
+            .queue = qid,
+    };
+
+
+    errval_t err = reg_port_filter(&f, fid);
+    assert(err_is_ok(err));
+    DEBUG("filter registered: err=%"PRIu64", fid=%"PRIu64"\n", err, *fid);
+    return SYS_ERR_OK;
+}
+
+
+static errval_t cb_remove_filter(struct net_filter_binding *b,
+                                 net_filter_filter_type_t type,
+                                 uint64_t filter_id,
+                                 errval_t* err)
+{
+    if ((type == net_filter_PORT_UDP || type == net_filter_PORT_TCP)
+        && filters_rx_ip[filter_id].enabled == true) {
+        filters_rx_ip[filter_id].enabled = false;  
+
+        sfn5122f_rx_filter_tbl_lo_wr(d, filter_id, 0);
+        sfn5122f_rx_filter_tbl_hi_wr(d, filter_id, 0);
+        *err = SYS_ERR_OK;
+    } else {
+        *err = NET_FILTER_ERR_NOT_FOUND;
+    }
+
+    DEBUG("unregister_filter: called (%"PRIx64")\n", filter_id);
+    return SYS_ERR_OK;
+}
+
+static struct net_filter_rpc_rx_vtbl net_filter_rpc_rx_vtbl = {
+    .install_filter_ip_call = cb_install_filter,
+    .remove_filter_call = cb_remove_filter,
+    .install_filter_mac_call = NULL,
+};
+
+static void net_filter_export_cb(void *st, errval_t err, iref_t iref)
+{
+
+    printf("exported net filter interface\n");
+    err = nameservice_register("net_filter_sfn5122f", iref);
+    assert(err_is_ok(err));
+    DEBUG("Net filter interface exported\n");
+}
+
+
+static errval_t net_filter_connect_cb(void *st, struct net_filter_binding *b)
+{
+    printf("New connection on net filter interface\n");
+    b->rpc_rx_vtbl = net_filter_rpc_rx_vtbl;
+    return SYS_ERR_OK;
+}
+
 /**
  * Initialize management interface for queue drivers.
  * This has to be done _after_ the hardware is initialized.
@@ -1598,19 +1678,26 @@ static void initialize_mngif(void)
 {
     errval_t r;
 
+    /*
     r = sfn5122f_export(NULL, export_cb, connect_cb, get_default_waitset(),
                     IDC_BIND_FLAGS_DEFAULT);
     assert(err_is_ok(r));
+    */
     r = sfn5122f_devif_export(NULL, export_devif_cb, connect_devif_cb,
                               get_default_waitset(), 1);
     assert(err_is_ok(r));
 
+    r = net_filter_export(NULL, net_filter_export_cb, net_filter_connect_cb,
+                          get_default_waitset(), 1);
+    assert(err_is_ok(r));
 }
 
+
 /*****************************************************************************/
 /* ARP service client */
 
 /** Get information about the local TCP/IP configuration*/
+/*
 static errval_t arp_ip_info(void)
 {
     errval_t err, msgerr;
@@ -1632,7 +1719,6 @@ static void a_bind_cb(void *st, errval_t err, struct net_ARP_binding *b)
     net_arp_connected = true;
 }
 
-/** Bind to ARP service (currently blocking) */
 static void bind_arp(struct waitset *ws)
 {
     errval_t err;
@@ -1653,7 +1739,7 @@ static void bind_arp(struct waitset *ws)
     }
     DEBUG("bound_arp\n");
 }
-
+*/
 
 /******************************************************************************/
 /* Initialization code for driver */