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 /******************************************************************************
31 ******************************************************************************/
34 static void bind_cb(void *st, errval_t err, struct net_filter_binding *b)
36 struct net_filter_state* filt = (struct net_filter_state*) st;
37 assert(err_is_ok(err));
39 NETDEBUG("Sucessfully connected to management interface\n");
42 net_filter_rpc_client_init(filt->b);
47 /** Open connection to management interface */
48 static errval_t connect_to_net_filter(struct net_filter_state* st,
53 const char* prefix = "net_filter_";
54 char name[strlen(dev_name) + strlen(prefix) + 1];
56 // Build label for management service
57 sprintf(name, "%s%s", prefix, dev_name);
59 NETDEBUG("Name lookup\n");
61 r = nameservice_blocking_lookup(name, &iref);
66 NETDEBUG("Binding\n");
67 r = net_filter_bind(iref, bind_cb, st, get_default_waitset(),
68 IDC_BIND_FLAGS_DEFAULT);
73 NETDEBUG("Waiting to bind\n");
74 while(st->bound == false) {
75 event_dispatch(get_default_waitset());
78 NETDEBUG("finished connecting\n");
82 /******************************************************************************
84 ******************************************************************************/
86 static bool filter_cmp_ip(struct net_filter_ip* f1, struct net_filter_ip* f2)
88 if (f1->ip_src == f2->ip_src &&
89 f1->ip_dst == f2->ip_dst &&
90 f1->port_src == f2->port_src &&
91 f1->port_dst == f2->port_dst &&
93 f1->type == f2->type) {
100 static bool filter_cmp_mac(struct net_filter_mac* f1, struct net_filter_mac* f2)
102 if (f1->vlan_id == f2->vlan_id &&
103 f1->mac == f2->mac &&
104 f1->type == f2->type) {
111 static bool is_reachable(struct net_filter_ip* filt)
113 struct net_filter_ele* cur = filter_state.filters_ip.start;
116 printf("reachable: port_dst: %"PRIu16" %"PRIu16" \n", cur->filter.ip.port_dst, filt->port_dst);
117 if (filter_cmp_ip(&cur->filter.ip, filt)) {
125 /******************************************************************************
126 * Library function implementation
127 ******************************************************************************/
130 * @brief initalized network filtering. Sets up connection to drivers
131 * which support hardware filtering
133 * @param st returned net filter state;
134 * @param cardname the card name to be used
136 * @return SYS_ERR_OK on success, error on failure
138 errval_t net_filter_init(struct net_filter_state** st,
139 const char* cardname)
143 struct net_filter_state* tmp = calloc(1, sizeof(struct net_filter_state));
146 tmp->filters_ip.start = NULL;
147 tmp->filters_ip.num_ele = 0;
148 tmp->filters_mac.start = NULL;
149 tmp->filters_mac.num_ele = 0;
151 err = connect_to_net_filter(tmp, cardname);
158 * @brief Installs an L3/L4 filter in the hardware filter
161 * @param st net filter state
162 * @param filt filter struct
164 * @return SYS_ERR_OK on success, error on failure
166 errval_t net_filter_ip_install(struct net_filter_state* st,
167 struct net_filter_ip* filt)
174 struct net_filter_ele* cur = st->filters_ip.start;
175 struct net_filter_ele* prev = NULL;
177 /* go through linked list and find last element
178 (and check if filter is already installed) */
180 st->filters_ip.start = malloc(sizeof(struct net_filter_ele));
181 cur = st->filters_ip.start;
183 while(cur->next != NULL) {
184 if (filter_cmp_ip(&cur->filter.ip, filt)) {
185 return NET_FILTER_ERR_ALREADY_EXISTS;
191 if (filter_cmp_ip(&cur->filter.ip, filt)) {
192 return NET_FILTER_ERR_ALREADY_EXISTS;
195 cur->next = malloc(sizeof(struct net_filter_ele));
199 cur->filter.ip.ip_src = filt->ip_src;
200 cur->filter.ip.ip_dst = filt->ip_dst;
201 cur->filter.ip.port_src = filt->port_src;
202 cur->filter.ip.port_dst = filt->port_dst;
203 cur->filter.ip.qid = filt->qid;
204 cur->filter.ip.type = filt->type;
208 st->filters_ip.num_ele++;
210 err = st->b->rpc_tx_vtbl.install_filter_ip(st->b,
218 if (err_is_fail(err)) {
223 cur->filter_id = filter_id;
229 * @brief Removes an L3/L4 filter in the hardware filter
232 * @param st net filter state
233 * @param filt filter struct
235 * @return SYS_ERR_OK on success, error on failure
237 errval_t net_filter_ip_remove(struct net_filter_state* st,
238 struct net_filter_ip* filt)
243 uint64_t filter_id = (uint64_t)-1;
245 struct net_filter_ele* cur = st->filters_ip.start;
246 struct net_filter_ele* prev = NULL;
251 return NET_FILTER_ERR_NOT_FOUND;
256 if (filter_cmp_ip(&cur->filter.ip, filt)) {
257 filter_id = cur->filter_id;
265 if (filter_id == (uint64_t) -1) {
266 return NET_FILTER_ERR_NOT_FOUND;
269 err = st->b->rpc_tx_vtbl.remove_filter(st->b,
273 if (err_is_fail(err) || err_is_fail(err2)) {
274 return err_is_fail(err) ? err: err2;
278 if (prev != NULL) { // check if first
279 prev->next = cur->next;
280 if (cur->next != NULL) { // check if last
281 cur->next->prev = prev;
284 st->filters_ip.start = cur->next;
290 st->filters_ip.num_ele--;
295 errval_t net_filter_mac_install(struct net_filter_state* st,
296 struct net_filter_mac* filt)
298 USER_PANIC("NYI \n");
302 errval_t net_filter_mac_remove(struct net_filter_state* st,
303 struct net_filter_mac* filt)
305 USER_PANIC("NYI \n");