1/** 2 * \file net_soft_filters_impl.c 3 * \brief Generic server part responsible for exporting net_soft_filter.if 4 * for most ethernet drivers. Current drivers using this server code are 5 * -- e1000n 6 * -- rtl8029 7 * -- eMAC 8 * -- e10k (within shared queue) 9 */ 10 11/* 12 * Copyright (c) 2007-11 ETH Zurich. 13 * All rights reserved. 14 * 15 * This file is distributed under the terms in the attached LICENSE file. 16 * If you do not find this file, copies can be found by writing to: 17 * ETH Zurich D-INFK, Haldeneggsteig 4, CH-8092 Zurich. Attn: Systems Group. 18 */ 19 20#include <barrelfish/barrelfish.h> 21#include <barrelfish/nameservice_client.h> 22#include <barrelfish/net_constants.h> 23#include <barrelfish/waitset_chan.h> 24 25#include <stdio.h> 26#include <string.h> 27#include <trace/trace.h> 28#include <trace_definitions/trace_defs.h> 29#include <net_queue_manager/net_queue_manager.h> 30#include <bfdmuxvm/vm.h> 31#include <if/net_soft_filters_defs.h> 32#include <if/net_soft_filters_defs.h> 33#include <if/net_queue_manager_defs.h> 34#include "queue_manager_local.h" 35#include "queue_manager_debug.h" 36 37#define RX_RING_MAXMEM 512*1024 38 39#if CONFIG_TRACE && NETWORK_STACK_TRACE 40#define TRACE_ONLY_SUB_NNET 1 41#endif // CONFIG_TRACE && NETWORK_STACK_TRACE 42 43/* This is client_closure for filter management */ 44struct client_closure_FM { 45 struct net_soft_filters_binding *app_connection; /* FIXME: Do I need this? */ 46/* FIXME: this should contain the registered buffer ptr */ 47}; 48 49static errval_t register_filter_memory(struct net_soft_filters_binding *cc, 50 struct capref mem_cap, errval_t *rerr); 51static errval_t register_filter(struct net_soft_filters_binding *cc, uint64_t id, 52 uint64_t len_rx, uint64_t len_tx, 53 uint64_t buffer_id_rx, uint64_t buffer_id_tx, 54 uint64_t ftype, uint64_t paused, errval_t *rerr, 55 uint64_t *filter_id); 56static errval_t register_arp_filter(struct net_soft_filters_binding *cc, uint64_t id, 57 uint64_t len_rx, uint64_t len_tx, errval_t *rerr); 58static errval_t deregister_filter(struct net_soft_filters_binding *cc, 59 uint64_t filter_id, errval_t *rerr); 60static errval_t re_register_filter(struct net_soft_filters_binding *cc, 61 uint64_t filter_id, uint64_t buffer_id_rx, 62 uint64_t buffer_id_tx, errval_t *rerr); 63static errval_t pause_filter(struct net_soft_filters_binding *cc, uint64_t filter_id, 64 uint64_t buffer_id_rx, uint64_t buffer_id_tx, errval_t *rerr); 65static errval_t mac_address_request_sf(struct net_soft_filters_binding *cc, 66 errval_t *rerr, uint64_t *mac); 67 68// Initialize interface for soft_filters channel 69static struct net_soft_filters_rpc_rx_vtbl rpc_rx_net_soft_filters_vtbl = { 70 .register_filter_memory_call = register_filter_memory, 71 .register_filter_call = register_filter, 72 .re_register_filter_call = re_register_filter, 73 .deregister_filter_call = deregister_filter, 74 .register_arp_filter_call = register_arp_filter, 75 .pause_call = pause_filter, 76 .mac_address_call = mac_address_request_sf, 77}; 78 79 80// Measurement purpose, counting interrupt numbers 81uint64_t total_processing_time = 0; 82uint64_t interrupt_counter = 0; 83uint64_t total_rx_p_count = 0; 84uint64_t total_interrupt_time = 0; 85struct client_closure *g_cl = NULL; 86uint64_t total_rx_datasize = 0; 87 88/***************************************************************** 89 * Local states: 90 *****************************************************************/ 91 92static char sf_srv_name[MAX_NET_SERVICE_NAME_LEN]; 93 94 95// rx ring 96static size_t rx_ring_size = 0; 97static size_t rx_ring_bufsz = 0; 98static uint64_t rx_ring_phys = 0; 99static void* rx_ring_virt = NULL; 100 101// filters state: 102static struct filter *rx_filters; 103static struct filter arp_filter_rx; 104static struct filter arp_filter_tx; 105 106static uint64_t filter_id_counter = 0; 107 108static void export_soft_filters_cb(void *st, errval_t err, iref_t iref) 109{ 110 char service_name[MAX_NET_SERVICE_NAME_LEN]; 111 struct net_soft_filter_state *state = st; 112 113 snprintf(service_name, sizeof(service_name), "%s%s", sf_srv_name, 114 FILTER_SERVICE_SUFFIX); 115 if (err_is_fail(err)) { 116 DEBUG_ERR(err, "service[%s] export failed", service_name); 117 abort(); 118 } 119 120 ETHERSRV_DEBUG("service [%s] exported at iref %u\n", service_name, iref); 121 122 // register this iref with the name service 123 err = nameservice_register(service_name, iref); 124 if (err_is_fail(err)) { 125 DEBUG_ERR(err, "nameservice_register failed for [%s]", service_name); 126 abort(); 127 } 128 waitset_chan_trigger(&state->initialization_completed); 129} 130 131static errval_t connect_soft_filters_cb(void *st, 132 struct net_soft_filters_binding *b) 133{ 134 ETHERSRV_DEBUG("ether_netd service got a connection!55\n"); 135 136 // copy my message receive handler vtable to the binding 137 b->rpc_rx_vtbl = rpc_rx_net_soft_filters_vtbl; 138 //b->error_handler = error_handler; 139 140 struct client_closure_FM *ccfm = 141 (struct client_closure_FM *) malloc(sizeof(struct client_closure_FM)); 142 143 b->st = ccfm; 144 ccfm->app_connection = b; 145 146 // FIXME: should I refuse more than one connections for FM services? 147 // Currently, I am accepting them 148 149 // accept the connection (we could return an error to refuse it) 150 return SYS_ERR_OK; 151} // end function: connect_soft_filters_cb 152 153/***************************************************************** 154 * filter registration 155 *****************************************************************/ 156 157static errval_t mac_address_request_sf(struct net_soft_filters_binding *cc, 158 errval_t *err, uint64_t *mac) 159{ 160 *err = SYS_ERR_OK; 161 *mac = get_mac_addr_from_device(); 162 return SYS_ERR_OK; 163} // end function: mac_address_request_sf 164 165static struct bulk_transfer_slave bt_filter_rx; 166 167static errval_t register_filter_memory(struct net_soft_filters_binding *cc, 168 struct capref mem_cap, errval_t *err) 169{ 170 *err = SYS_ERR_OK; 171 172 struct frame_identity pa; 173 174 *err = frame_identify(mem_cap, &pa); 175 if(!err_is_ok(*err)) { 176 printf("invoke_frame_identity failed\n"); 177 abort(); 178 } 179 180 ETHERSRV_DEBUG("register_netd_memory: attempt to register memory\n"); 181 // 2 is rx + tx 182 if (pa.bytes < BASE_PAGE_SIZE * 2) { 183 ETHERSRV_DEBUG("netd did not provided enough for filter transfer\n"); 184 *err = FILTER_ERR_NOT_ENOUGH_MEMORY; /* ps: FIXME: enable this error */ 185 186 } /* end if: not enough memory */ 187 else { /* enough memory, try to map it */ 188 void *pool; 189 190 *err = vspace_map_one_frame_attr((void *) (&pool), BASE_PAGE_SIZE * 2, 191 mem_cap, 192 VREGION_FLAGS_READ_WRITE_NOCACHE, NULL, 193 NULL); 194 195 if (err_is_fail(*err)) { 196 DEBUG_ERR(*err, "vspace_map_one_frame failed"); 197 // abort(); 198 } /* end if: mapping failed */ 199 else { 200 // Init receiver 201 *err = bulk_slave_init(pool, BASE_PAGE_SIZE * 2, &bt_filter_rx); 202 // assert(err_is_ok(err)); 203 204 } /* end else: mapping sucessful */ 205 206 } /* end else : */ 207 return SYS_ERR_OK; 208} /* end function : register_netd_memory */ 209 210/** 211 * \brief: Registers the filter with network driver 212 */ 213static errval_t register_filter(struct net_soft_filters_binding *cc, uint64_t id, 214 uint64_t len_rx, uint64_t len_tx, 215 uint64_t buffer_id_rx, uint64_t buffer_id_tx, 216 uint64_t ftype, uint64_t paused, errval_t *err, 217 uint64_t *filter_id) 218{ 219 *err = SYS_ERR_OK; 220 221 struct buffer_descriptor *buffer_rx = NULL; 222 struct buffer_descriptor *buffer_tx = NULL; 223 struct buffer_descriptor *tmp = buffers_list; 224 225 while (tmp) { 226 227 if (tmp->buffer_id == buffer_id_tx) { 228 buffer_tx = tmp; 229 } 230 231 if (tmp->buffer_id == buffer_id_rx) { 232 buffer_rx = tmp; 233 } 234 235 if (buffer_rx != NULL && buffer_tx != NULL) { 236 break; 237 } 238 239 tmp = tmp->next; 240 } /* end while : */ 241 242 if (buffer_rx == NULL || buffer_tx == NULL) { 243 ETHERSRV_DEBUG("no buffer found for the provided buffer id\n"); 244 *err = FILTER_ERR_BUFF_NOT_FOUND; 245 *filter_id = 0; 246 return SYS_ERR_OK; 247 } 248 249 if (len_rx > BASE_PAGE_SIZE) { 250 len_rx = BASE_PAGE_SIZE; 251 } 252 253 if (len_tx > BASE_PAGE_SIZE) { 254 len_tx = BASE_PAGE_SIZE; 255 } 256 257 /* using id to find the location of memory */ 258 void *buf = bulk_slave_buf_get_mem(&bt_filter_rx, id, NULL); 259 260 if (buf == NULL) { 261 ETHERSRV_DEBUG("no memory available for filter transfer\n"); 262 *err = FILTER_ERR_NO_NETD_MEM; 263 *filter_id = 0; 264 return SYS_ERR_OK; 265 } 266 267 /* Create the filter data-structures */ 268 struct filter *new_filter_rx = 269 (struct filter *) malloc(sizeof(struct filter)); 270 struct filter *new_filter_tx = 271 (struct filter *) malloc(sizeof(struct filter)); 272 273 /* FIXME: use goto to deal with failure conditions and reduce the code */ 274 if (new_filter_rx == NULL || new_filter_tx == NULL) { 275 ETHERSRV_DEBUG("out of memory for filter registration\n"); 276 *err = ETHERSRV_ERR_NOT_ENOUGH_MEM; 277 *filter_id = 0; 278 279 if (new_filter_rx) { 280 free(new_filter_rx); 281 } 282 283 if (new_filter_tx) { 284 free(new_filter_tx); 285 } 286 return SYS_ERR_OK; 287 } 288 289 /* Zero out the filters */ 290 memset(new_filter_rx, 0, sizeof(struct filter)); 291 memset(new_filter_tx, 0, sizeof(struct filter)); 292 293 /* Allocate memory for holding the filter-data */ 294 new_filter_rx->data = (uint8_t *) malloc(len_rx); 295 new_filter_tx->data = (uint8_t *) malloc(len_tx); 296 297 if (new_filter_rx->data == NULL || new_filter_tx->data == NULL) { 298 ETHERSRV_DEBUG("out of memory for filter data registration\n"); 299 *err = ETHERSRV_ERR_NOT_ENOUGH_MEM; 300 *filter_id = 0; 301 302 if (new_filter_rx->data) { 303 free(new_filter_rx->data); 304 } 305 306 if (new_filter_tx->data) { 307 free(new_filter_tx->data); 308 } 309 310 free(new_filter_rx); 311 free(new_filter_tx); 312 313 return SYS_ERR_OK; 314 } 315 316 /* Zero-out the area of filter-data */ 317 memset(new_filter_rx->data, 0, len_rx); 318 memset(new_filter_tx->data, 0, len_tx); 319 320 filter_id_counter++; 321 322 // rx filter 323 memcpy(new_filter_rx->data, buf, len_rx); 324 new_filter_rx->len = len_rx; 325 new_filter_rx->filter_id = filter_id_counter; 326 new_filter_rx->filter_type = ftype; 327 new_filter_rx->buffer = buffer_rx; 328 new_filter_rx->next = rx_filters; 329 new_filter_rx->paused = paused ? true : false; 330 rx_filters = new_filter_rx; 331 ETHERSRV_DEBUG("filter registered with id %" PRIu64 " and len %d\n", 332 new_filter_rx->filter_id, new_filter_rx->len); 333 334 // tx filter 335 void *bbuf_tx = buf + BASE_PAGE_SIZE; 336 337 memcpy(new_filter_tx->data, bbuf_tx, len_tx); 338 new_filter_tx->len = len_tx; 339 new_filter_tx->filter_id = filter_id_counter; 340 new_filter_tx->filter_type = ftype; 341 new_filter_tx->buffer = buffer_tx; // we do not really need to set this 342 /* FIXME: following linked list implementation looks buggy */ 343 new_filter_tx->next = buffer_tx->tx_filters; 344 buffer_tx->tx_filters = new_filter_tx; 345 /* FIXME: following looks buggy!!! */ 346 buffer_rx->tx_filters = new_filter_tx; // sometimes rx buffers transmit 347 348 /* reporting back the success/failure */ 349 *filter_id = filter_id_counter; 350 return SYS_ERR_OK; 351} /* end function: register filter */ 352 353static struct filter *delete_from_filter_list(struct filter *head, 354 uint64_t filter_id) 355{ 356 struct filter *prev = NULL; 357 358 while (head != NULL) { 359 if (head->filter_id == filter_id) { 360 if (prev == NULL) { 361 rx_filters = head->next; 362 } else { 363 prev->next = head->next; 364 } 365 return head; 366 } /* end if: filter_id found */ 367 } /* end while: for each element in list */ 368 return NULL; /* could not not find the id. */ 369} 370 371/** 372 * \brief: Deregisters the filter with network driver 373 */ 374static errval_t deregister_filter(struct net_soft_filters_binding *cc, 375 uint64_t filter_id, errval_t *err) 376{ 377 *err = SYS_ERR_OK; 378 379 ETHERSRV_DEBUG("DeRegister_filter: ID:%" PRIu64 "\n", filter_id); 380 381 /* Create the filter data-structures */ 382 struct filter *rx_filter = NULL; 383 struct filter *tx_filter = NULL; 384 385 rx_filter = delete_from_filter_list(rx_filters, filter_id); 386 /* FIXME: delete the tx_filter from the filter list "buffer_rx->tx_filters" */ 387// tx_filter = delete_from_filter_list(tx_filters, filter_id); 388 389 if (rx_filter == NULL /*|| tx_filter == NULL */ ) { 390 ETHERSRV_DEBUG("Deregister_filter:requested filter_ID [%" PRIu64 391 "] not found\n", filter_id); 392 *err = FILTER_ERR_FILTER_NOT_FOUND; 393 } 394 395 if (rx_filter) { 396 free(rx_filter); 397 } 398 399 if (tx_filter) { 400 free(tx_filter); 401 } 402 403 /* reporting back the success/failure */ 404 ETHERSRV_DEBUG("Deregister_filter: ID %" PRIu64 ": Done\n", filter_id); 405 406 return SYS_ERR_OK; 407} /* end function: deregister_filter */ 408 409static struct filter *find_from_filter_list(struct filter *head, 410 uint64_t filter_id) 411{ 412 while (head != NULL) { 413 if (head->filter_id == filter_id) { 414 return head; 415 } /* end if: filter_id found */ 416 head = head->next; 417 } /* end while: for each element in list */ 418 return NULL; /* could not not find the id. */ 419} 420 421/** 422 * \brief: re-registers the filter with network driver 423 */ 424static errval_t re_register_filter(struct net_soft_filters_binding *cc, 425 uint64_t filter_id, uint64_t buffer_id_rx, 426 uint64_t buffer_id_tx, errval_t *err) 427{ 428 *err = SYS_ERR_OK; 429 430 ETHERSRV_DEBUG("re_register_filter: ID:%" PRIu64 "\n", filter_id); 431 432 /* Create the filter data-structures */ 433 struct filter *rx_filter = NULL; 434 435// struct filter *tx_filter = NULL; 436 437 rx_filter = find_from_filter_list(rx_filters, filter_id); 438 /* FIXME: delete the tx_filter from the filter list "buffer_rx->tx_filters" */ 439// tx_filter = delete_from_filter_list(tx_filters, filter_id); 440 441 if (rx_filter == NULL /*|| tx_filter == NULL */ ) { 442 ETHERSRV_DEBUG("re_register_filter: requested filter_ID [%" PRIu64 443 "] not found\n", filter_id); 444 *err = FILTER_ERR_FILTER_NOT_FOUND; 445 return SYS_ERR_OK; 446 } 447 448 /* Find the buffer with given buffer_id */ 449 struct buffer_descriptor *buffer_rx = find_buffer(buffer_id_rx); 450 struct buffer_descriptor *buffer_tx = NULL; 451 452 buffer_tx = find_buffer(buffer_id_tx); 453 if (buffer_rx == NULL || buffer_rx == NULL) { 454 ETHERSRV_DEBUG("re_register_filter: provided buffer id's not found\n"); 455 ETHERSRV_DEBUG("re_register_filter: rx=[[%" PRIu64 "] = %p], tx=[[%" 456 PRIu64 "] = %p]\n", buffer_id_rx, buffer_rx, 457 buffer_id_tx, buffer_tx); 458 *err = FILTER_ERR_BUFFER_NOT_FOUND; /* set error value */ 459 return SYS_ERR_OK; 460 } 461 rx_filter->buffer = buffer_rx; 462 /* FIXME: Also, set the new buffer for tx_filters */ 463 /* reporting back the success/failure */ 464 ETHERSRV_DEBUG("re_register_filter: ID %" PRIu64 ": Done\n", filter_id); 465 466 return SYS_ERR_OK; 467} /* end function: re_register_filter */ 468 469/** 470 * \brief: pause the filter with network driver 471 */ 472static errval_t pause_filter(struct net_soft_filters_binding *cc, uint64_t filter_id, 473 uint64_t buffer_id_rx, uint64_t buffer_id_tx, errval_t *err) 474{ 475 *err = SYS_ERR_OK; 476 477 ETHERSRV_DEBUG("(un)pause_filter: ID:%" PRIu64 "\n", filter_id); 478 479 /* Create the filter data-structures */ 480 struct filter *rx_filter = NULL; 481 482// struct filter *tx_filter = NULL; 483 484 rx_filter = find_from_filter_list(rx_filters, filter_id); 485 /* FIXME: delete the tx_filter from the filter list "buffer_rx->tx_filters" */ 486// tx_filter = delete_from_filter_list(tx_filters, filter_id); 487 488 if (rx_filter == NULL /*|| tx_filter == NULL */ ) { 489 ETHERSRV_DEBUG("pause_filter: requested filter_ID [%" PRIu64 490 "] not found\n", filter_id); 491 *err = FILTER_ERR_FILTER_NOT_FOUND; 492 assert(!"NYI"); 493 /* wrapper_send_filter_re_register_msg(cc, err, filter_id, */ 494 /* buffer_id_rx, buffer_id_tx); */ 495 return SYS_ERR_OK; 496 } 497 498 /* Find the buffer with given buffer_id */ 499 struct buffer_descriptor *buffer_rx = find_buffer(buffer_id_rx); 500 struct buffer_descriptor *buffer_tx = NULL; 501 502 buffer_tx = find_buffer(buffer_id_tx); 503 if (buffer_rx == NULL || buffer_rx == NULL) { 504 ETHERSRV_DEBUG("re_register_filter: provided buffer id's not found\n"); 505 ETHERSRV_DEBUG("re_register_filter: rx=[[%" PRIu64 "] = %p], tx=[[%" 506 PRIu64 "] = %p]\n", buffer_id_rx, buffer_rx, 507 buffer_id_tx, buffer_tx); 508 assert(!"NYI"); 509 /* err = FILTER_ERR_BUFFER_NOT_FOUND; /\* set error value *\/ */ 510 /* wrapper_send_filter_re_register_msg(cc, err, filter_id, buffer_id_rx, */ 511 /* buffer_id_tx); */ 512 } 513 rx_filter->buffer = buffer_rx; 514 /* FIXME: Also, set the new buffer for tx_filters */ 515 /* reporting back the success/failure */ 516 517 rx_filter->paused = false; 518 if (rx_filter->pause_bufpos > 0) { 519 for (int i = 0; i < rx_filter->pause_bufpos; i++) { 520 struct bufdesc *bd = &rx_filter->pause_buffer[i]; 521 522 struct devq *q = rx_filter->buffer->device_queue; 523 assert(q != NULL); 524 struct client_closure *cl = devq_get_state(q); 525 assert(cl != NULL); 526 copy_packet_to_user(rx_filter->buffer, bd->pkt_data, bd->pkt_len, 527 bd->flags); 528 } 529 } 530 rx_filter->pause_bufpos = 0; 531 532 ETHERSRV_DEBUG("(un)pause_filter: ID %" PRIu64 ": Done\n", filter_id); 533 return SYS_ERR_OK; 534} /* end function: re_register_filter */ 535 536static errval_t register_arp_filter(struct net_soft_filters_binding *cc, uint64_t id, 537 uint64_t len_rx, uint64_t len_tx, errval_t *err) 538{ 539 *err = SYS_ERR_OK; 540 541 if (len_rx > BASE_PAGE_SIZE) { 542 len_rx = BASE_PAGE_SIZE; 543 } 544 if (len_tx > BASE_PAGE_SIZE) { 545 len_tx = BASE_PAGE_SIZE; 546 } 547 548 /* using id to find the location of memory */ 549 void *buf = bulk_slave_buf_get_mem(&bt_filter_rx, id, NULL); 550 551 if (buf == NULL) { 552 ETHERSRV_DEBUG("no memory available for arp_filter transfer\n"); 553 *err = FILTER_ERR_NO_NETD_MEM; 554 return SYS_ERR_OK; 555 } 556 557 arp_filter_rx.data = (uint8_t *) malloc(len_rx); 558 assert(arp_filter_rx.data); 559 memcpy(arp_filter_rx.data, buf, len_rx); 560 arp_filter_rx.len = len_rx; 561 ETHERSRV_DEBUG("#### The received arp RX filter is\n"); 562 // show_binary_blob(arp_filter_rx.data, arp_filter_rx.len); 563 564 void *bbuf_tx = buf + BASE_PAGE_SIZE; 565 566 arp_filter_tx.data = (uint8_t *) malloc(len_tx); 567 assert(arp_filter_tx.data); 568 memcpy(arp_filter_tx.data, bbuf_tx, len_tx); 569 arp_filter_tx.len = len_tx; 570 ETHERSRV_DEBUG("#### The received arp RX filter is\n"); 571 // show_binary_blob(arp_filter_tx.data, arp_filter_tx.len); 572 return SYS_ERR_OK; 573} 574 575static void send_arp_to_all(void *data, uint64_t len, uint64_t flags) 576{ 577 struct filter *head = rx_filters; 578 579 ETHERSRV_DEBUG("### Sending the ARP packet to all, %"PRIx64" \n", len); 580 /* sending ARP packets to only those who have registered atleast one 581 * filter with e1000n 582 * */ 583 584 /* FIXME: this code will send two copies or ARP if there are two filters 585 * registered, which is incorrect. Fix it. */ 586 struct devq *q = NULL; 587 struct client_closure *cl = NULL; 588 while (head) { 589 q = head->buffer->device_queue; 590 assert(q != NULL); 591 cl = devq_get_state(q); 592 assert(cl != NULL); 593 copy_packet_to_user(head->buffer, data, len, flags); 594 head = head->next; 595 } 596 597 if(waiting_for_netd()){ 598 return; 599 } 600 // Forwarding it to netd as well. 601 struct buffer_descriptor *buffer = ((struct client_closure *)devq_get_state(netd[RECEIVE_CONNECTION]))->buffer_ptr; 602 603 604#if TRACE_ETHERSRV_MODE 605 trace_event(TRACE_SUBSYS_NET, TRACE_EVENT_NET_NI_ARP, 606 (uint32_t) (uintptr_t) data); 607#endif // TRACE_ETHERSRV_MODE 608 609 copy_packet_to_user(buffer, data, len, flags); 610} 611 612struct filter *execute_filters(void *data, size_t len) 613{ 614 struct filter *head = rx_filters; 615 int res, error; 616 617 int i = 0; 618 619// ETHERSRV_DEBUG("Starting the filter matching....\n"); 620 // TODO: gracefully handle the error cases, although I think 621 // it is not really necessary. since it could only mean we have 622 // received a corrupted packet. 623 while (head) { 624 res = execute_filter(head->data, head->len, (uint8_t *) data, 625 len, &error); 626 if (res) { 627 // FIXME IK: we need some way of testing how precise a match is 628 // and take the most precise match (ie with the least wildcards) 629 // Currently we just take the most recently added filter as 630 // reflected by the order in the list. 631 ETHERSRV_DEBUG("##### Filter_id [%" PRIu64 "] type[%" PRIu64 632 "] matched giving buff [%" PRIu64 "].., len [%" PRIu64 "]\n", 633 head->filter_id, head->filter_type, 634 head->buffer->buffer_id, len); 635 return head; 636 } 637 head = head->next; 638 ++i; 639 } 640 return NULL; 641} 642 643/** Return virtual address for RX buffer. */ 644static void* rx_ring_buffer(void *opaque) 645{ 646 size_t idx = (size_t) opaque; 647 648/* printf("rx_ring_size %zd, idx %zd rx_ring_bufsz %zd\n", 649 rx_ring_size, idx, rx_ring_bufsz); 650*/ 651 652 assert(idx < rx_ring_size); 653 654 return ((void*) ((uintptr_t) rx_ring_virt + idx * rx_ring_bufsz)); 655} 656 657/** Register a RX buffer with the driver. */ 658static void rx_ring_register_buffer(void *opaque) 659{ 660 size_t offset; 661 size_t idx = (size_t) opaque; 662 663 offset = idx * rx_ring_bufsz; 664 rx_register_buffer_fn_ptr(rx_ring_phys + offset, 665 ((void*) ((uintptr_t) rx_ring_virt + offset)), opaque); 666} 667 668static void init_rx_ring(size_t rx_bufsz) 669{ 670 struct capref frame; 671 errval_t r; 672 struct frame_identity frameid = { .base = 0, .bytes = 0 }; 673 size_t capacity = rx_get_free_slots_fn_ptr(); 674 size_t size; 675 size_t i; 676 677 rx_ring_bufsz = rx_bufsz; 678 rx_ring_size = MIN(RX_RING_MAXMEM / rx_bufsz, capacity); 679 ETHERSRV_DEBUG("rx_ring_size %zd %zd\n", rx_ring_size, capacity); 680 // TODO: Should I round up here to page size? 681 size = rx_ring_size * rx_bufsz; 682 683 r = frame_alloc(&frame, size, NULL); 684 if (!err_is_ok(r)) { 685 USER_PANIC("Allocating RX buffers for SW filtering failed!"); 686 } 687 688 r = frame_identify(frame, &frameid); 689 if (!err_is_ok(r)) { 690 USER_PANIC("Identifying RX frame for SW filtering failed!"); 691 } 692 rx_ring_phys = frameid.base; 693 694 r = vspace_map_one_frame_attr(&rx_ring_virt, size, frame, 695 VREGION_FLAGS_READ_WRITE, NULL, NULL); 696 if (!err_is_ok(r)) { 697 USER_PANIC("Mapping RX frame for SW filtering failed!"); 698 } 699 memset(rx_ring_virt, 0, size); 700 701 702 // Add buffers to RX ring 703 for (i = 0; i < rx_ring_size; i++) { 704 rx_ring_register_buffer((void*) i); 705 } 706} 707 708void init_soft_filters_service(struct net_soft_filter_state *state, char *service_name, uint64_t qid, 709 size_t rx_bufsz) 710{ 711 // FIXME: do I need separate sf_srv_name for ether_netd services 712 // exporting ether_netd interface 713 714 // Initialize receive buffers 715 init_rx_ring(rx_bufsz); 716 717 filter_id_counter = 0; 718 snprintf(sf_srv_name, sizeof(sf_srv_name), "%s_%"PRIu64"", 719 service_name, qid); 720 errval_t err = net_soft_filters_export(state, export_soft_filters_cb, 721 connect_soft_filters_cb, get_default_waitset(), 722 IDC_EXPORT_FLAGS_DEFAULT); 723 if (err_is_fail(err)) { 724 DEBUG_ERR(err, "ethersrv_netd export failed"); 725 abort(); 726 } 727 728} // end function: init_soft_filters_service 729 730 731// Checks if packet belongs to specific application and sends to it 732static bool handle_application_packet(void *packet, size_t len, uint64_t flags) 733{ 734 735 // executing filters to find the relevant buffer 736 uint64_t ts = rdtsc(); 737 struct filter *filter = execute_filters(packet, len); 738 739 if (filter == NULL) { 740 // No matching filter 741 return false; 742 } 743 744 745#if TRACE_ONLY_SUB_NNET 746 trace_event(TRACE_SUBSYS_NNET, TRACE_EVENT_NNET_RXESVAPPFDONE, 747 (uint32_t) ((uintptr_t) packet)); 748#endif // TRACE_ONLY_SUB_NNET 749 750 751 // Matching filter found, sending packet to application 752 struct buffer_descriptor *buffer = filter->buffer; 753 struct devq *q = buffer->device_queue; 754 assert(q != NULL); 755 struct client_closure *cl = devq_get_state(q); 756 assert(cl != NULL); 757 758 if (cl->debug_state == 4) { 759// printf("packet for application arrived!!\n"); 760 netbench_record_event_simple(bm, RE_FILTER, ts); 761 } 762 763 if (cl->debug_state == 3) { 764 // Trigger to start the recording the stats 765 ts = rdtsc(); 766 cl->start_ts = ts; 767 cl->debug_state = 4; 768 interrupt_counter = 0; 769 total_rx_p_count = 0; 770 total_interrupt_time = 0; 771 total_processing_time = 0; 772 total_rx_datasize = 0; 773 g_cl = cl; 774 trace_event(TRACE_SUBSYS_NNET, TRACE_EVENT_NNET_START, 0); 775 } 776 777 if (filter->paused) { 778 // Packet belongs to paused filter 779 assert(filter->pause_bufpos < MAX_PAUSE_BUFFER); 780 struct bufdesc *bd = &filter->pause_buffer[filter->pause_bufpos++]; 781 782// memcpy_fast(bd->pkt_data, packet, len); 783 bd->pkt_len = len; 784 bd->flags = flags; 785 return true; 786 } 787 788 // Normal case 789 if (cl->debug_state == 4) { 790 ++cl->in_filter_matched; 791 } 792 793#if TRACE_ONLY_SUB_NNET 794 trace_event(TRACE_SUBSYS_NNET, TRACE_EVENT_NNET_RXESVAPPCSTART, 795 (uint32_t) ((uintptr_t) packet)); 796#endif // TRACE_ONLY_SUB_NNET 797 798 bool ret = copy_packet_to_user(buffer, packet, len, flags); 799 if (ret) { 800 // Packet delivered to the application buffer 801 if (cl->debug_state == 4) { 802 ++cl->in_filter_matched_p; 803 804/* 805 if ((cl->in_filter_matched_p % 1000 ) == 0 ) { 806 printf("@@@@@@ D: %"PRIu64" packets arrived\n", 807 cl->in_filter_matched_p); 808 } 809*/ 810 netbench_record_event_simple(bm, RE_USEFUL, ts); 811 } 812 813 } else { 814 // Could not deliver the packet to application! 815 if (cl->debug_state == 4) { 816 ++cl->in_filter_matched_f; 817 netbench_record_event_simple(bm, RE_DROPPED, ts); 818 } 819// printf("A: Copy packet to userspace failed\n"); 820 } 821 return true; 822} // end function: handle_application_packet 823 824// Checks if packet is of ARP type 825// If YES, then send it to all 826static bool handle_arp_packet(void *packet, size_t len, uint64_t flags) 827{ 828 int error; 829 830 if (arp_filter_rx.data == NULL) { 831 return false; 832 } 833 834 bool res = execute_filter(arp_filter_rx.data, arp_filter_rx.len, 835 (uint8_t *) packet, len, &error); 836 837 if (res) { // we have an arp packet 838// ETHERSRV_DEBUG("ARP packet...\n"); 839 send_arp_to_all(packet, len, flags); 840 return true; 841 } 842 843 return false; 844} // end function: handle_arp_packet 845 846 847// give this packet to netd 848static bool handle_netd_packet(void *packet, size_t len, uint64_t flags) 849{ 850 if(waiting_for_netd()){ 851// ETHERSRV_DEBUG("waiting for netd\n"); 852 return false; 853 } 854 855 ETHERSRV_DEBUG("No client wants, giving it to netd\n"); 856 struct buffer_descriptor *buffer = ((struct client_closure *)devq_get_state(netd[RECEIVE_CONNECTION]))->buffer_ptr; 857 858// ETHERSRV_DEBUG("sending packet up.\n"); 859 /* copy the packet to userspace */ 860 if(buffer == NULL) { 861 printf("netd buffer not present\n"); 862 return false; 863 } 864 865 struct devq *q = buffer->device_queue; 866 if(q == NULL) { 867 printf("netd buffer->con not present\n"); 868 return false; 869 } 870 871 struct client_closure *cl = devq_get_state(q); 872 assert(cl != NULL); 873 if (copy_packet_to_user(buffer, packet, len, flags) == false) { 874 ETHERSRV_DEBUG("Copy packet to userspace failed\n"); 875 } 876 ETHERSRV_DEBUG("packet handled by netd\n"); 877 return true; 878} // end function: handle_netd_packet 879 880#if 0 // LOOPBACK 881// give this packet to netd 882static bool handle_loopback_packet(void *packet, size_t len, void *opaque, 883 uint64_t flags) 884{ 885 886 ETHERSRV_DEBUG("sending up the loopback packet\n"); 887 888 // FIXME: get the receiver buffer 889 struct buffer_descriptor *buffer = get_lo_receiver(opaque); 890 891// ETHERSRV_DEBUG("sending packet up.\n"); 892 /* copy the packet to userspace */ 893 if(buffer == NULL) { 894 printf("no loopback receiver found\n"); 895 return false; 896 } 897 898 struct net_queue_manager_binding *b = buffer->con; 899 if(b == NULL) { 900 printf("destination buffer->con not present\n"); 901 return false; 902 } 903 904 struct client_closure *cl = (struct client_closure *)b->st; 905 assert(cl != NULL); 906 if (copy_packet_to_user(buffer, packet, len, flags) == false) { 907 ETHERSRV_DEBUG("Copy packet to userspace failed\n"); 908 } 909 return true; 910} // end function: handle_loopback_packet 911 912 913void sf_process_received_packet_lo(void *opaque_rx, void *opaque_tx, 914 size_t pkt_len, bool is_last, uint64_t flags) 915{ 916 void *pkt_data; 917 918 ETHERSRV_DEBUG("pkt_len %zd and rx_ring_bufsz %zd\n", pkt_len, 919 rx_ring_bufsz); 920 assert(pkt_len <= rx_ring_bufsz); 921 // FIXME: allow packets to be distributed over multiple buffers 922 assert(is_last); 923 924 // Get the virtual address for this buffer 925 pkt_data = rx_ring_buffer(opaque_rx); 926 927#if TRACE_ETHERSRV_MODE 928 uint32_t pkt_location = (uint32_t) ((uintptr_t) pkt_data); 929 trace_event(TRACE_SUBSYS_NET, TRACE_EVENT_NET_NI_A, pkt_location); 930#endif // TRACE_ETHERSRV_MODE 931#if TRACE_ONLY_SUB_NNET 932 trace_event(TRACE_SUBSYS_NNET, TRACE_EVENT_NNET_RXESVSEE, 933 (uint32_t) ((uintptr_t) pkt_data)); 934#endif // TRACE_ONLY_SUB_NNET 935 936 if (is_loopback_device) { 937 if(handle_loopback_packet(pkt_data, pkt_len, opaque_tx, flags)) { 938 goto out; 939 } else { 940 USER_PANIC("handle_loopback_packet failed"); 941 } 942 } 943 944out: 945 rx_ring_register_buffer(opaque_rx); 946} // end function: sf_process_received_packet_lo 947#endif 948 949 950void sf_process_received_packet(struct driver_rx_buffer *buf, size_t count, 951 uint64_t flags) 952{ 953 void *pkt_data; 954 void *opaque; 955 size_t pkt_len; 956 957 // FIXME: allow packets to be distributed over multiple buffers 958 assert(count == 1); 959 960 opaque = buf[0].opaque; 961 pkt_len = buf[0].len; 962 // Get the virtual address for this buffer 963 pkt_data = rx_ring_buffer(opaque); 964 965 assert(pkt_len <= rx_ring_bufsz); 966 967#if TRACE_ETHERSRV_MODE 968 uint32_t pkt_location = (uint32_t) ((uintptr_t) pkt_data); 969 trace_event(TRACE_SUBSYS_NET, TRACE_EVENT_NET_NI_A, pkt_location); 970#endif // TRACE_ETHERSRV_MODE 971#if TRACE_ONLY_SUB_NNET 972 trace_event(TRACE_SUBSYS_NNET, TRACE_EVENT_NNET_RXESVSEE, 973 (uint32_t) ((uintptr_t) pkt_data)); 974#endif // TRACE_ONLY_SUB_NNET 975 976#if 0 // LOOPBACK 977 if (is_loopback_device) { 978 if(handle_loopback_packet(pkt_data, pkt_len, opaque, flags)) { 979 goto out; 980 } else { 981 USER_PANIC("handle_loopback_packet failed"); 982 } 983 } 984#endif 985 986 // check for fragmented packet 987 if (handle_fragmented_packet(pkt_data, pkt_len, flags)) { 988 ETHERSRV_DEBUG("fragmented packet..\n"); 989 goto out; 990 } 991 992#if TRACE_ONLY_SUB_NNET 993 trace_event(TRACE_SUBSYS_NNET, TRACE_EVENT_NNET_RXESVFRGDONE, 994 (uint32_t) ((uintptr_t) pkt_data)); 995#endif // TRACE_ONLY_SUB_NNET 996 997 // check for application specific packet 998 if (handle_application_packet(pkt_data, pkt_len, flags)) { 999 ETHERSRV_DEBUG 1000 //printf 1001 ("application specific packet.. len %"PRIu64"\n", pkt_len); 1002 goto out; 1003 } 1004 1005 // check for ARP packet 1006 if (handle_arp_packet(pkt_data, pkt_len, flags)) { 1007 ETHERSRV_DEBUG 1008 ("ARP packet..\n"); 1009 goto out; 1010 } 1011 1012 // last resort: send packet to netd 1013 1014 ETHERSRV_DEBUG("orphan packet, goes to netd..\n"); 1015 handle_netd_packet(pkt_data, pkt_len, flags); 1016 1017out: 1018 rx_ring_register_buffer(opaque); 1019} // end function: process_received_packet 1020