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 <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 // cardname are of the form name:vendor:device:bus:function ..
153 for (; end < strlen(cardname); end++) {
154 if (cardname[end] == ':') {
160 strncpy(name, cardname, end);
163 printf("cardname %s \n", name);
164 err = connect_to_net_filter(tmp, name);
171 * @brief Installs an L3/L4 filter in the hardware filter
174 * @param st net filter state
175 * @param filt filter struct
177 * @return SYS_ERR_OK on success, error on failure
179 errval_t net_filter_ip_install(struct net_filter_state* st,
180 struct net_filter_ip* filt)
187 struct net_filter_ele* cur = st->filters_ip.start;
188 struct net_filter_ele* prev = NULL;
190 /* go through linked list and find last element
191 (and check if filter is already installed) */
193 st->filters_ip.start = malloc(sizeof(struct net_filter_ele));
194 cur = st->filters_ip.start;
196 while(cur->next != NULL) {
197 if (filter_cmp_ip(&cur->filter.ip, filt)) {
198 return NET_FILTER_ERR_ALREADY_EXISTS;
204 if (filter_cmp_ip(&cur->filter.ip, filt)) {
205 return NET_FILTER_ERR_ALREADY_EXISTS;
208 cur->next = malloc(sizeof(struct net_filter_ele));
212 cur->filter.ip.ip_src = filt->ip_src;
213 cur->filter.ip.ip_dst = filt->ip_dst;
214 cur->filter.ip.port_src = filt->port_src;
215 cur->filter.ip.port_dst = filt->port_dst;
216 cur->filter.ip.qid = filt->qid;
217 cur->filter.ip.type = filt->type;
221 st->filters_ip.num_ele++;
223 err = st->b->rpc_tx_vtbl.install_filter_ip(st->b,
231 if (err_is_fail(err)) {
236 cur->filter_id = filter_id;
242 * @brief Removes an L3/L4 filter in the hardware filter
245 * @param st net filter state
246 * @param filt filter struct
248 * @return SYS_ERR_OK on success, error on failure
250 errval_t net_filter_ip_remove(struct net_filter_state* st,
251 struct net_filter_ip* filt)
256 uint64_t filter_id = (uint64_t)-1;
258 struct net_filter_ele* cur = st->filters_ip.start;
259 struct net_filter_ele* prev = NULL;
264 return NET_FILTER_ERR_NOT_FOUND;
269 if (filter_cmp_ip(&cur->filter.ip, filt)) {
270 filter_id = cur->filter_id;
278 if (filter_id == (uint64_t) -1) {
279 return NET_FILTER_ERR_NOT_FOUND;
282 err = st->b->rpc_tx_vtbl.remove_filter(st->b,
286 if (err_is_fail(err) || err_is_fail(err2)) {
287 return err_is_fail(err) ? err: err2;
291 if (prev != NULL) { // check if first
292 prev->next = cur->next;
293 if (cur->next != NULL) { // check if last
294 cur->next->prev = prev;
297 st->filters_ip.start = cur->next;
303 st->filters_ip.num_ele--;
308 errval_t net_filter_mac_install(struct net_filter_state* st,
309 struct net_filter_mac* filt)
311 USER_PANIC("NYI \n");
315 errval_t net_filter_mac_remove(struct net_filter_state* st,
316 struct net_filter_mac* filt)
318 USER_PANIC("NYI \n");