libnet: avoid failing setting up filter with e1000 like cardnames
[barrelfish] / lib / net / net_filter.c
index d1781e5..1ed167b 100644 (file)
@@ -17,7 +17,7 @@
 #include <if/net_filter_defs.h>
 #include <if/net_filter_rpcclient_defs.h>
 
-#include "include/net/net_filter.h"
+#include <net/net_filter.h>
 
 #include "networking_internal.h"
 #include "debug.h"
 
 #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
  ******************************************************************************/
@@ -62,18 +33,20 @@ static struct net_filter_state filter_state;
 // Callback for bind
 static void bind_cb(void *st, errval_t err, struct net_filter_binding *b)
 {
+    struct net_filter_state* filt = (struct net_filter_state*) st;
     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;
+    filt->b = b;
+    net_filter_rpc_client_init(filt->b);
+    filt->bound = true;
 }
 
 
 /** Open connection to management interface */
-static errval_t connect_to_net_filter(const char *dev_name)
+static errval_t connect_to_net_filter(struct net_filter_state* st,
+                                      const char *dev_name)
 {
     errval_t r;
     iref_t iref;
@@ -91,14 +64,14 @@ static errval_t connect_to_net_filter(const char *dev_name)
     }
 
     NETDEBUG("Binding\n");
-    r = net_filter_bind(iref, bind_cb, &filter_state, get_default_waitset(),
+    r = net_filter_bind(iref, bind_cb, st, get_default_waitset(),
             IDC_BIND_FLAGS_DEFAULT);
     if (err_is_fail(r)) {
         return r;
     }
 
     NETDEBUG("Waiting to bind\n");
-    while(filter_state.bound == false) {
+    while(st->bound == false) {
         event_dispatch(get_default_waitset());
     }
     
@@ -157,47 +130,68 @@ static bool is_reachable(struct net_filter_ip* filt)
  * @brief initalized network filtering. Sets up connection to drivers
  *        which support hardware filtering
  *
- * @param cardname  returns the card name to be used
+ * @param st        returned net filter state;
+ * @param cardname  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 net_filter_init(struct net_filter_state** st,
+                         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;
+    struct net_filter_state* tmp = calloc(1, sizeof(struct net_filter_state));
+    assert(tmp != NULL);
+    
+    tmp->filters_ip.start = NULL;
+    tmp->filters_ip.num_ele = 0;
+    tmp->filters_mac.start = NULL;
+    tmp->filters_mac.num_ele = 0;
+
+    // cardname are of the form name:vendor:device:bus:function ..
+    int end = 0;
+    for (; end < strlen(cardname); end++) {
+        if (cardname[end] == ':') {
+            break;
+        }
+    }
+
+    char name[64];
+    strncpy(name, cardname, end);
+    name[end] = '\0';
 
-    err = connect_to_net_filter(cardname);
+    printf("cardname %s \n", name);
+    err = connect_to_net_filter(tmp, name);
+    *st = tmp;
     return err;
 }
 
 
 /**
- * @brief Installs an L3/L4 filter in the hardware filter 
+ * @brief Installs an L3/L4 filter in the hardware filter
  *        tables
  *
+ * @param st    net filter state
  * @param filt  filter struct
  *
  * @return SYS_ERR_OK on success, error on failure
  */
-errval_t net_filter_ip_install(struct net_filter_ip* filt)
+errval_t net_filter_ip_install(struct net_filter_state* st,
+                               struct net_filter_ip* filt)
 {
 
-    assert(filter_state.bound);
+    assert(st->bound);
     errval_t err;
     uint64_t filter_id;
 
-    struct net_filter_ele* cur = filter_state.filters_ip.start;
+    struct net_filter_ele* cur = st->filters_ip.start;
     struct net_filter_ele* prev = NULL;
 
-    /* go through linked list and find last element 
+    /* 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;
+        st->filters_ip.start = malloc(sizeof(struct net_filter_ele));
+        cur = st->filters_ip.start;
     } else {
         while(cur->next != NULL) {
             if (filter_cmp_ip(&cur->filter.ip, filt)) {
@@ -222,18 +216,18 @@ errval_t net_filter_ip_install(struct net_filter_ip* filt)
     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);
+    cur->prev = prev;
+
+    st->filters_ip.num_ele++;
+
+    err = st->b->rpc_tx_vtbl.install_filter_ip(st->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;
@@ -245,21 +239,23 @@ errval_t net_filter_ip_install(struct net_filter_ip* filt)
 
 
 /**
- * @brief Removes an L3/L4 filter in the hardware filter 
+ * @brief Removes an L3/L4 filter in the hardware filter
  *        tables
  *
+ * @param st    net filter state
  * @param filt  filter struct
  *
  * @return SYS_ERR_OK on success, error on failure
  */
-errval_t net_filter_ip_remove(struct net_filter_ip* filt)
+errval_t net_filter_ip_remove(struct net_filter_state* st,
+                              struct net_filter_ip* filt)
 {
 
-    assert(filter_state.bound);
+    assert(st->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* cur = st->filters_ip.start;
     struct net_filter_ele* prev = NULL;
 
 
@@ -272,7 +268,6 @@ errval_t net_filter_ip_remove(struct net_filter_ip* filt)
     while(cur != NULL) {
         if (filter_cmp_ip(&cur->filter.ip, filt)) {
             filter_id = cur->filter_id;
-            printf("Break \n");
             break;
         }
         prev = cur;
@@ -284,10 +279,10 @@ errval_t net_filter_ip_remove(struct net_filter_ip* filt)
         return NET_FILTER_ERR_NOT_FOUND;
     }
 
-    err = filter_state.b->rpc_tx_vtbl.remove_filter(filter_state.b,
-                                                    filt->type,
-                                                    filter_id,
-                                                    &err2);
+    err = st->b->rpc_tx_vtbl.remove_filter(st->b,
+                                           filt->type,
+                                           filter_id,
+                                           &err2);
     if (err_is_fail(err) || err_is_fail(err2)) {
         return err_is_fail(err) ? err: err2;
     }
@@ -297,30 +292,28 @@ errval_t net_filter_ip_remove(struct net_filter_ip* filt)
         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;
+        st->filters_ip.start = cur->next;
     }
     
 
     free(cur);
 
-    filter_state.filters_ip.num_ele--;
+    st->filters_ip.num_ele--;
 
     return SYS_ERR_OK;
 }
 
-errval_t net_filter_mac_install(struct net_filter_mac* filt)
+errval_t net_filter_mac_install(struct net_filter_state* st,
+                                struct net_filter_mac* filt)
 {
    USER_PANIC("NYI \n");
 }
 
 
-errval_t net_filter_mac_remove(struct net_filter_mac* filt)
+errval_t net_filter_mac_remove(struct net_filter_state* st,
+                               struct net_filter_mac* filt)
 {
    USER_PANIC("NYI \n");
 }
-