};
+//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
"xomp_gateway",
"sfn5122f",
"sfn5122f_devif",
- "descq"
+ "descq",
+ "net_filter"
],
arch <- allArchitectures
] ++
--- /dev/null
+/*
+ * 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);
+
+};
+
[ 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",
--- /dev/null
+/**
+ * @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_ */
#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"
}
+ 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);
}
}
-
if (flags & NET_FLAGS_DO_DHCP) {
err = dhcpd_start(flags);
if (err_is_fail(err)) {
--- /dev/null
+/*
+ * 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");
+}
+
#include <lwip/udp.h>
#include <lwip/pbuf.h>
#include <net/net.h>
+#include <net/net_filter.h>
#define UDP_ECHOSERVER_PORT 7
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);
"rtl8029",
"serial_pc16550d",
"sfxge",
+ "sfn5122f",
"slideshow",
"sshd",
"vbe",
"vnode_map_test",
"webserver",
"xeon_phi",
- "xeon_phi_mgr"
+ "xeon_phi_mgr",
]] ++ modules_common
-- the following are broken in the newidc system
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",
#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>
#include "buffer_tbl.h"
#include "sfn5122f_qdriver.h"
+
struct queue_state {
bool enabled;
bool userspace;
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
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,
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 */
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,
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);
return tmp ^ tmp >> 9;
}
+/*
static bool filter_equals(struct sfn5122f_filter_ip* f1,
struct sfn5122f_filter_ip* f2)
{
return true;
}
}
-
+*/
static uint16_t filter_increment(uint32_t key)
{
return key * 2 - 1;
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;
return key;
}
-
static errval_t reg_port_filter(struct sfn5122f_filter_ip* f, uint64_t* fid)
{
int filt_ind;
}
}
+/*
static errval_t idc_terminate_queue(struct sfn5122f_binding *b, uint16_t n)
{
DEBUG("idc_terminate_queue(q=%d) \n", n);
{
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);
}
*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,
.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)
.deregister_region_call = cd_deregister_region,
};
+/*
static void export_cb(void *st, errval_t err, iref_t iref)
{
const char *suffix = "_sfn5122fmng";
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";
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.
{
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;
net_arp_connected = true;
}
-/** Bind to ARP service (currently blocking) */
static void bind_arp(struct waitset *ws)
{
errval_t err;
}
DEBUG("bound_arp\n");
}
-
+*/
/******************************************************************************/
/* Initialization code for driver */