479 } else {
480 /*
481 * We need to make sure that this 'flow' is not deleted
482 * either by a scheduled timeout or an explict call
483 * to flowacct_timer() below.
484 */
485 flow->inuse = B_TRUE;
486 }
487
488 ihead = &flow->items;
489 item = flowacct_item_present(flow, header->dsfield, header->projid,
490 header->uid);
491 if (item == NULL) {
492 boolean_t just_once = B_TRUE;
493 /*
494 * For all practical purposes, we limit the no. of entries in
495 * the flow table - i.e. the max_limt that a user specifies is
496 * the maximum no. of flow items in the table.
497 */
498 try_again:
499 atomic_add_32(&flowacct_data->nflows, 1);
500 if (flowacct_data->nflows > flowacct_data->max_limit) {
501 atomic_add_32(&flowacct_data->nflows, -1);
502
503 /* Try timing out once */
504 if (just_once) {
505 /*
506 * Need to release the lock, as this entry
507 * could contain a flow that can be timed
508 * out.
509 */
510 mutex_exit(&fhead->lock);
511 flowacct_timer(FLOWACCT_JUST_ONE,
512 flowacct_data);
513 mutex_enter(&fhead->lock);
514 /* Lets check again */
515 just_once = B_FALSE;
516 goto try_again;
517 } else {
518 flow->inuse = B_FALSE;
519 /* Need to remove the flow, if one was added */
520 if (added_flow) {
521 flowacct_del_obj(fhead, flow->hdr,
522 FLOWACCT_DEL_OBJ);
523 }
524 mutex_exit(&fhead->lock);
525 flowacct1dbg(("flowacct_update_flows_tbl: "\
526 "maximum active flows exceeded\n"));
527 return (-1);
528 }
529 }
530 item = (flow_item_t *)kmem_zalloc(FLOWACCT_ITEM_SZ, KM_NOSLEEP);
531 if (item == NULL) {
532 flow->inuse = B_FALSE;
533 /* Need to remove the flow, if one was added */
534 if (added_flow) {
535 flowacct_del_obj(fhead, flow->hdr,
536 FLOWACCT_DEL_OBJ);
537 }
538 mutex_exit(&fhead->lock);
539 atomic_add_32(&flowacct_data->nflows, -1);
540 flowacct0dbg(("flowacct_update_flows_tbl: mem alloc "\
541 "error"));
542 return (-1);
543 }
544 item->hdr = flowacct_add_obj(ihead, ihead->tail, (void *)item);
545 if (item->hdr == NULL) {
546 flow->inuse = B_FALSE;
547 /* Need to remove the flow, if one was added */
548 if (added_flow) {
549 flowacct_del_obj(fhead, flow->hdr,
550 FLOWACCT_DEL_OBJ);
551 }
552 mutex_exit(&fhead->lock);
553 atomic_add_32(&flowacct_data->nflows, -1);
554 kmem_free(item, FLOWACCT_ITEM_SZ);
555 flowacct0dbg(("flowacct_update_flows_tbl: mem alloc "\
556 "error\n"));
557 return (-1);
558 }
559 /* If a flow was added, add it too */
560 if (added_flow) {
561 atomic_add_64(&flowacct_data->usedmem,
562 FLOWACCT_FLOW_RECORD_SZ);
563 }
564 atomic_add_64(&flowacct_data->usedmem, FLOWACCT_ITEM_RECORD_SZ);
565
566 item->type = FLOWACCT_ITEM;
567 item->dsfield = header->dsfield;
568 item->projid = header->projid;
569 item->uid = header->uid;
570 item->npackets = 1;
571 item->nbytes = header->pktlen;
572 item->creation_time = item->hdr->last_seen;
573 } else {
870
871 /*
872 * Get the IP header contents from the packet, update the flow table with
873 * this item and return.
874 */
875 int
876 flowacct_process(mblk_t **mpp, flowacct_data_t *flowacct_data)
877 {
878 header_t *header;
879 mblk_t *mp = *mpp;
880
881 ASSERT(mp != NULL);
882
883 /* If we don't find an M_DATA, return error */
884 if (mp->b_datap->db_type != M_DATA) {
885 if ((mp->b_cont != NULL) &&
886 (mp->b_cont->b_datap->db_type == M_DATA)) {
887 mp = mp->b_cont;
888 } else {
889 flowacct0dbg(("flowacct_process: no data\n"));
890 atomic_add_64(&flowacct_data->epackets, 1);
891 return (EINVAL);
892 }
893 }
894
895 header = kmem_zalloc(FLOWACCT_HEADER_SZ, KM_NOSLEEP);
896 if (header == NULL) {
897 flowacct0dbg(("flowacct_process: error allocing mem"));
898 atomic_add_64(&flowacct_data->epackets, 1);
899 return (ENOMEM);
900 }
901
902 /* Get all the required information into header. */
903 if (flowacct_extract_header(mp, header) != 0) {
904 kmem_free(header, FLOWACCT_HEADER_SZ);
905 atomic_add_64(&flowacct_data->epackets, 1);
906 return (EINVAL);
907 }
908
909 /* Updated the flow table with this entry */
910 if (flowacct_update_flows_tbl(header, flowacct_data) != 0) {
911 kmem_free(header, FLOWACCT_HEADER_SZ);
912 atomic_add_64(&flowacct_data->epackets, 1);
913 return (ENOMEM);
914 }
915
916 /* Update global stats */
917 atomic_add_64(&flowacct_data->npackets, 1);
918 atomic_add_64(&flowacct_data->nbytes, header->pktlen);
919
920 kmem_free(header, FLOWACCT_HEADER_SZ);
921 if (flowacct_data->flow_tid == 0) {
922 flowacct_data->flow_tid = timeout(flowacct_timeout_flows,
923 flowacct_data, drv_usectohz(flowacct_data->timer));
924 }
925 return (0);
926 }
|
479 } else {
480 /*
481 * We need to make sure that this 'flow' is not deleted
482 * either by a scheduled timeout or an explict call
483 * to flowacct_timer() below.
484 */
485 flow->inuse = B_TRUE;
486 }
487
488 ihead = &flow->items;
489 item = flowacct_item_present(flow, header->dsfield, header->projid,
490 header->uid);
491 if (item == NULL) {
492 boolean_t just_once = B_TRUE;
493 /*
494 * For all practical purposes, we limit the no. of entries in
495 * the flow table - i.e. the max_limt that a user specifies is
496 * the maximum no. of flow items in the table.
497 */
498 try_again:
499 atomic_inc_32(&flowacct_data->nflows);
500 if (flowacct_data->nflows > flowacct_data->max_limit) {
501 atomic_dec_32(&flowacct_data->nflows);
502
503 /* Try timing out once */
504 if (just_once) {
505 /*
506 * Need to release the lock, as this entry
507 * could contain a flow that can be timed
508 * out.
509 */
510 mutex_exit(&fhead->lock);
511 flowacct_timer(FLOWACCT_JUST_ONE,
512 flowacct_data);
513 mutex_enter(&fhead->lock);
514 /* Lets check again */
515 just_once = B_FALSE;
516 goto try_again;
517 } else {
518 flow->inuse = B_FALSE;
519 /* Need to remove the flow, if one was added */
520 if (added_flow) {
521 flowacct_del_obj(fhead, flow->hdr,
522 FLOWACCT_DEL_OBJ);
523 }
524 mutex_exit(&fhead->lock);
525 flowacct1dbg(("flowacct_update_flows_tbl: "\
526 "maximum active flows exceeded\n"));
527 return (-1);
528 }
529 }
530 item = (flow_item_t *)kmem_zalloc(FLOWACCT_ITEM_SZ, KM_NOSLEEP);
531 if (item == NULL) {
532 flow->inuse = B_FALSE;
533 /* Need to remove the flow, if one was added */
534 if (added_flow) {
535 flowacct_del_obj(fhead, flow->hdr,
536 FLOWACCT_DEL_OBJ);
537 }
538 mutex_exit(&fhead->lock);
539 atomic_dec_32(&flowacct_data->nflows);
540 flowacct0dbg(("flowacct_update_flows_tbl: mem alloc "\
541 "error"));
542 return (-1);
543 }
544 item->hdr = flowacct_add_obj(ihead, ihead->tail, (void *)item);
545 if (item->hdr == NULL) {
546 flow->inuse = B_FALSE;
547 /* Need to remove the flow, if one was added */
548 if (added_flow) {
549 flowacct_del_obj(fhead, flow->hdr,
550 FLOWACCT_DEL_OBJ);
551 }
552 mutex_exit(&fhead->lock);
553 atomic_dec_32(&flowacct_data->nflows);
554 kmem_free(item, FLOWACCT_ITEM_SZ);
555 flowacct0dbg(("flowacct_update_flows_tbl: mem alloc "\
556 "error\n"));
557 return (-1);
558 }
559 /* If a flow was added, add it too */
560 if (added_flow) {
561 atomic_add_64(&flowacct_data->usedmem,
562 FLOWACCT_FLOW_RECORD_SZ);
563 }
564 atomic_add_64(&flowacct_data->usedmem, FLOWACCT_ITEM_RECORD_SZ);
565
566 item->type = FLOWACCT_ITEM;
567 item->dsfield = header->dsfield;
568 item->projid = header->projid;
569 item->uid = header->uid;
570 item->npackets = 1;
571 item->nbytes = header->pktlen;
572 item->creation_time = item->hdr->last_seen;
573 } else {
870
871 /*
872 * Get the IP header contents from the packet, update the flow table with
873 * this item and return.
874 */
875 int
876 flowacct_process(mblk_t **mpp, flowacct_data_t *flowacct_data)
877 {
878 header_t *header;
879 mblk_t *mp = *mpp;
880
881 ASSERT(mp != NULL);
882
883 /* If we don't find an M_DATA, return error */
884 if (mp->b_datap->db_type != M_DATA) {
885 if ((mp->b_cont != NULL) &&
886 (mp->b_cont->b_datap->db_type == M_DATA)) {
887 mp = mp->b_cont;
888 } else {
889 flowacct0dbg(("flowacct_process: no data\n"));
890 atomic_inc_64(&flowacct_data->epackets);
891 return (EINVAL);
892 }
893 }
894
895 header = kmem_zalloc(FLOWACCT_HEADER_SZ, KM_NOSLEEP);
896 if (header == NULL) {
897 flowacct0dbg(("flowacct_process: error allocing mem"));
898 atomic_inc_64(&flowacct_data->epackets);
899 return (ENOMEM);
900 }
901
902 /* Get all the required information into header. */
903 if (flowacct_extract_header(mp, header) != 0) {
904 kmem_free(header, FLOWACCT_HEADER_SZ);
905 atomic_inc_64(&flowacct_data->epackets);
906 return (EINVAL);
907 }
908
909 /* Updated the flow table with this entry */
910 if (flowacct_update_flows_tbl(header, flowacct_data) != 0) {
911 kmem_free(header, FLOWACCT_HEADER_SZ);
912 atomic_inc_64(&flowacct_data->epackets);
913 return (ENOMEM);
914 }
915
916 /* Update global stats */
917 atomic_inc_64(&flowacct_data->npackets);
918 atomic_add_64(&flowacct_data->nbytes, header->pktlen);
919
920 kmem_free(header, FLOWACCT_HEADER_SZ);
921 if (flowacct_data->flow_tid == 0) {
922 flowacct_data->flow_tid = timeout(flowacct_timeout_flows,
923 flowacct_data, drv_usectohz(flowacct_data->timer));
924 }
925 return (0);
926 }
|