2 * Copyright (c) 2017, ETH Zurich.
5 * This file is distributed under the terms in the attached LICENSE file.
6 * If you do not find this file, copies can be found by writing to:
7 * ETH Zurich D-INFK, Universitaetsstrasse 6, CH-8092 Zurich. Attn: Systems Group.
15 #include <barrelfish/barrelfish.h>
16 #include <barrelfish/nameservice_client.h>
17 #include <if/net_filter_defs.h>
18 #include <if/net_filter_rpcclient_defs.h>
20 #include "include/net/net_filter.h"
22 #include "networking_internal.h"
27 #define NETDEBUG_SUBSYSTEM "filter"
29 struct net_filter_ele {
31 struct net_filter_ip ip;
32 struct net_filter_mac mac;
35 struct net_filter_ele* next;
36 struct net_filter_ele* prev;
40 struct net_filter_ele* start;
44 struct net_filter_state {
45 struct filter_list filters_ip;
46 struct filter_list filters_mac;
47 struct net_filter_binding* b;
52 /******************************************************************************
54 ******************************************************************************/
56 static struct net_filter_state filter_state;
58 /******************************************************************************
60 ******************************************************************************/
63 static void bind_cb(void *st, errval_t err, struct net_filter_binding *b)
65 assert(err_is_ok(err));
67 NETDEBUG("Sucessfully connected to management interface\n");
70 net_filter_rpc_client_init(filter_state.b);
71 filter_state.bound = true;
75 /** Open connection to management interface */
76 static errval_t connect_to_net_filter(const char *dev_name)
80 const char* prefix = "net_filter_";
81 char name[strlen(dev_name) + strlen(prefix) + 1];
83 // Build label for management service
84 sprintf(name, "%s%s", prefix, dev_name);
86 NETDEBUG("Name lookup\n");
88 r = nameservice_blocking_lookup(name, &iref);
93 NETDEBUG("Binding\n");
94 r = net_filter_bind(iref, bind_cb, &filter_state, get_default_waitset(),
95 IDC_BIND_FLAGS_DEFAULT);
100 NETDEBUG("Waiting to bind\n");
101 while(filter_state.bound == false) {
102 event_dispatch(get_default_waitset());
105 NETDEBUG("finished connecting\n");
109 /******************************************************************************
111 ******************************************************************************/
113 static bool filter_cmp_ip(struct net_filter_ip* f1, struct net_filter_ip* f2)
115 if (f1->ip_src == f2->ip_src &&
116 f1->ip_dst == f2->ip_dst &&
117 f1->port_src == f2->port_src &&
118 f1->port_dst == f2->port_dst &&
119 f1->qid == f2->qid &&
120 f1->type == f2->type) {
127 static bool filter_cmp_mac(struct net_filter_mac* f1, struct net_filter_mac* f2)
129 if (f1->vlan_id == f2->vlan_id &&
130 f1->mac == f2->mac &&
131 f1->type == f2->type) {
138 static bool is_reachable(struct net_filter_ip* filt)
140 struct net_filter_ele* cur = filter_state.filters_ip.start;
143 printf("reachable: port_dst: %"PRIu16" %"PRIu16" \n", cur->filter.ip.port_dst, filt->port_dst);
144 if (filter_cmp_ip(&cur->filter.ip, filt)) {
152 /******************************************************************************
153 * Library function implementation
154 ******************************************************************************/
157 * @brief initalized network filtering. Sets up connection to drivers
158 * which support hardware filtering
160 * @param cardname returns the card name to be used
162 * @return SYS_ERR_OK on success, error on failure
164 errval_t net_filter_init(const char* cardname)
168 filter_state.filters_ip.start = NULL;
169 filter_state.filters_ip.num_ele = 0;
170 filter_state.filters_mac.start = NULL;
171 filter_state.filters_mac.num_ele = 0;
173 err = connect_to_net_filter(cardname);
179 * @brief Installs an L3/L4 filter in the hardware filter
182 * @param filt filter struct
184 * @return SYS_ERR_OK on success, error on failure
186 errval_t net_filter_ip_install(struct net_filter_ip* filt)
189 assert(filter_state.bound);
193 struct net_filter_ele* cur = filter_state.filters_ip.start;
194 struct net_filter_ele* prev = NULL;
196 /* go through linked list and find last element
197 (and check if filter is already installed) */
199 filter_state.filters_ip.start = malloc(sizeof(struct net_filter_ele));
200 cur = filter_state.filters_ip.start;
202 while(cur->next != NULL) {
203 if (filter_cmp_ip(&cur->filter.ip, filt)) {
204 return NET_FILTER_ERR_ALREADY_EXISTS;
210 if (filter_cmp_ip(&cur->filter.ip, filt)) {
211 return NET_FILTER_ERR_ALREADY_EXISTS;
214 cur->next = malloc(sizeof(struct net_filter_ele));
218 cur->filter.ip.ip_src = filt->ip_src;
219 cur->filter.ip.ip_dst = filt->ip_dst;
220 cur->filter.ip.port_src = filt->port_src;
221 cur->filter.ip.port_dst = filt->port_dst;
222 cur->filter.ip.qid = filt->qid;
223 cur->filter.ip.type = filt->type;
227 filter_state.filters_ip.num_ele++;
229 err = filter_state.b->rpc_tx_vtbl.install_filter_ip(filter_state.b,
237 if (err_is_fail(err)) {
242 cur->filter_id = filter_id;
248 * @brief Removes an L3/L4 filter in the hardware filter
251 * @param filt filter struct
253 * @return SYS_ERR_OK on success, error on failure
255 errval_t net_filter_ip_remove(struct net_filter_ip* filt)
258 assert(filter_state.bound);
260 uint64_t filter_id = (uint64_t)-1;
262 struct net_filter_ele* cur = filter_state.filters_ip.start;
263 struct net_filter_ele* prev = NULL;
268 return NET_FILTER_ERR_NOT_FOUND;
273 if (filter_cmp_ip(&cur->filter.ip, filt)) {
274 filter_id = cur->filter_id;
283 if (filter_id == (uint64_t) -1) {
284 return NET_FILTER_ERR_NOT_FOUND;
287 err = filter_state.b->rpc_tx_vtbl.remove_filter(filter_state.b,
291 if (err_is_fail(err) || err_is_fail(err2)) {
292 return err_is_fail(err) ? err: err2;
296 if (prev != NULL) { // check if first
297 prev->next = cur->next;
298 if (cur->next != NULL) { // check if last
299 cur->next->prev = prev;
300 printf("cur->next->prev id %d \n", cur->next->prev->filter.ip.port_dst);
301 printf("prev->next id %d \n", prev->next->filter.ip.port_dst);
304 printf("start id %d \n", filter_state.filters_ip.start->filter.ip.port_dst);
305 filter_state.filters_ip.start = cur->next;
311 filter_state.filters_ip.num_ele--;
316 errval_t net_filter_mac_install(struct net_filter_mac* filt)
318 USER_PANIC("NYI \n");
322 errval_t net_filter_mac_remove(struct net_filter_mac* filt)
324 USER_PANIC("NYI \n");