Example #1
0
static void *processing_loop_egress(void *arg) {
  pipeline_t *pipeline = (pipeline_t *) arg;
  circular_buffer_t *cb_in = pipeline->cb_in;

  //Added by Ming
#ifdef SWITCH_CPU_DEBUG
  int i;
#endif

#ifdef RATE_LIMITING
  struct timeval tv;
  gettimeofday(&tv, NULL);
  uint64_t next_deque = tv.tv_sec * 1000000 + tv.tv_usec + read_atomic_int(&USEC_INTERVAL);
#endif

  while(1) {
#ifdef RATE_LIMITING
    struct timeval tv;
    gettimeofday(&tv, NULL);
    uint64_t now_us = tv.tv_sec * 1000000 + tv.tv_usec;
    //RMT_LOG(P4_LOG_LEVEL_TRACE, "next_deque %lu, now_us %lu\n", next_deque, now_us);
    if(next_deque > now_us) {
      usleep(next_deque - now_us);
    }
    next_deque += read_atomic_int(&USEC_INTERVAL);
#endif
    egress_pkt_t *e_pkt = (egress_pkt_t *) cb_read(cb_in);
    if (e_pkt == NULL) continue;
    buffered_pkt_t *b_pkt = &e_pkt->pkt;
    RMT_LOG(P4_LOG_LEVEL_TRACE, "egress_pipeline: packet dequeued\n");

    phv_clean(pipeline->phv);

    pipeline->phv->packet_id = b_pkt->pkt_id;

    parser_parse_pkt(pipeline->phv,
		     b_pkt->pkt_data, b_pkt->pkt_len,
		     pipeline->parse_state_start);
    parser_parse_metadata(pipeline->phv,
			  e_pkt->metadata, e_pkt->metadata_recirc);
    assert(!fields_get_clone_spec(pipeline->phv));

//::  if enable_intrinsic:
   /* Set dequeue metadata */
    fields_set_deq_qdepth(pipeline->phv, cb_count(cb_in));
    uint64_t enq_timestamp = fields_get_enq_timestamp(pipeline->phv);
    fields_set_deq_timedelta(pipeline->phv, get_timestamp()-enq_timestamp);
//::  #endif

    fields_set_instance_type(pipeline->phv, e_pkt->pkt.instance_type);

    free(e_pkt->metadata);
    free(e_pkt->metadata_recirc);
    if(pipeline->table_entry_fn)  /* empty egress pipeline ? */
      pipeline->table_entry_fn(pipeline->phv);

    uint8_t *pkt_data;
    int pkt_len;

    /* EGRESS MIRRORING */
    if(fields_get_clone_spec(pipeline->phv)) {
      RMT_LOG(P4_LOG_LEVEL_VERBOSE, "Egress mirroring\n");
      pipeline->deparse_fn(pipeline->phv, &pkt_data, &pkt_len);
      egress_cloning(pipeline, pkt_data, pkt_len, e_pkt->pkt.pkt_id);
      fields_set_clone_spec(pipeline->phv, 0);
    }

    update_checksums(pipeline->phv);
    pipeline->deparse_fn(pipeline->phv, &pkt_data, &pkt_len);

    free(b_pkt->pkt_data);

//:: if "egress_drop_ctl" in extra_metadata_name_map:
      // program uses the separate egress_drop_ctl register
      // a non-zero value means drop
    if(pipeline->phv->deparser_drop_signal ||
       metadata_get_egress_drop_ctl(metadata)) {
//:: else:
    if(pipeline->phv->deparser_drop_signal){
//:: #endif
      RMT_LOG(P4_LOG_LEVEL_VERBOSE, "dropping packet at egress\n");
      free(e_pkt);
      continue;
    }

    int egress = fields_get_egress_port(pipeline->phv);

    if(pipeline->phv->truncated_length && (pipeline->phv->truncated_length < pkt_len))
      pkt_len = pipeline->phv->truncated_length;
   
#ifdef SWITCH_CPU_DEBUG
	RMT_LOG(P4_LOG_LEVEL_TRACE, "Ming Packet Data: %d\n", b_pkt->pkt_len);
	for (i = 0; i < 21; i++)
		RMT_LOG(P4_LOG_LEVEL_TRACE, "%x ", b_pkt->pkt_data[i]);
	RMT_LOG(P4_LOG_LEVEL_TRACE, "\n");
#endif

    pkt_manager_transmit(egress, pkt_data, pkt_len, b_pkt->pkt_id);
    free(e_pkt);

  }

  return NULL;
}

/* name has to be ingress or egress */
pipeline_t *pipeline_create(int id) {
  pipeline_t *pipeline = malloc(sizeof(pipeline_t));
  pipeline->name = "egress";
#ifdef RATE_LIMITING
  pipeline->cb_in = cb_init(read_atomic_int(&EGRESS_CB_SIZE), CB_WRITE_DROP, CB_READ_RETURN);
#else
  pipeline->cb_in = cb_init(read_atomic_int(&EGRESS_CB_SIZE), CB_WRITE_BLOCK, CB_READ_BLOCK);
#endif
  pipeline->parse_state_start = parse_state_start;
//:: if egress_entry_table is not None:
  pipeline->table_entry_fn = tables_apply_${egress_entry_table};
//:: else:
  pipeline->table_entry_fn = NULL;
//:: #endif
  pipeline->deparse_fn = deparser_produce_pkt;
  pipeline->phv = phv_init(NB_THREADS_PER_PIPELINE + id, RMT_PIPELINE_EGRESS);

  /* packet processing loop */
  pthread_create(&pipeline->processing_thread, NULL,
		 processing_loop_egress, (void *) pipeline);

  return pipeline;
}
Example #2
0
/*
 * NAME:	cmdbuf->substitute()
 * DESCRIPTION:	do substitutions on a range of lines
 */
int cb_subst(cmdbuf *cb)
{
    char buf[MAX_LINE_SIZE], delim;
    Int m[26];
    Int edit;
    const char *p;
    Int *k, *l;

    delim = cb->cmd[0];
    if (delim == '\0' || strchr("0123456789gpl#-+", delim) != (char*) NULL) {
	/* no search pattern & replace string specified */
	if (cb->search[0] == '\0') {
	    error("No previous substitute to repeat");
	}
    } else if (!isalpha(delim)) {
	char *q;

	/* get search pattern */
	p = pattern(cb->cmd + 1, delim, cb->search);
	/* get replace string */
	q = cb->replace;
	while (*p != '\0') {
	    if (*p == delim) {
		p++;
		break;
	    }
	    if (q == cb->replace + STRINGSZ - 1) {
		cb->search[0] = '\0';
		error("Replace string too large");
	    }
	    if ((*q++ = *p++) == '\\' && *p != '\0') {
		*q++ = *p++;
	    }
	}
	*q = '\0';
	cb->cmd = p;
    } else {
	/* cause error */
	cb->search[0] = '\0';
    }

    if (cb->search[0] == '\0') {
	error("Missing regular expression for substitute");
    }

    /* compile regexp */
    p = rx_comp(cb->regexp, cb->search);
    if (p != (char *) NULL) {
	error(p);
    }

    cb_count(cb);	/* get count */
    /* handle global flag */
    if (cb->cmd[0] == 'g') {
	cb->flags |= CB_GLOBSUBST;
	cb->cmd++;
    } else {
	cb->flags &= ~CB_GLOBSUBST;
    }

    /* make a blank mark table */
    cb->moffset = m;
    for (l = m; l < &m[26]; ) {
	*l++ = 0;
    }
    cb->offset = 0;

    /* do substitutions */
    cb_do(cb, cb->first);
    cb->lineno = cb->first;
    edit = cb->edit;
    cb->buffer = buf;
    cb->buflen = 0;
    cb->flags &= ~(CB_CURRENTBLK | CB_SKIPPED);
    eb_range(cb->edbuf, cb->first, cb->last, subst, FALSE);
    if (cb->flags & CB_CURRENTBLK) {
	/* finish current block, if needed */
	endblock(cb);
    }

    cb->othis = cb->uthis;
    if (edit != cb->edit) {
	/* some marks may have been messed up. fix them */
	for (l = m, k = cb->mark; l < &m[26]; l++, k++) {
	    if (*l != 0) {
		*k = *l;
	    }
	}
    } else if (!(cb->flags & CB_GLOBAL)) {
	error("Substitute pattern match failed");
    }

    return RET_FLAGS;
}
Example #3
0
int egress_pipeline_count(int egress) {
  pipeline_t *pipeline = egress_pipeline_instances[egress %
						   NB_THREADS_PER_PIPELINE];
  return cb_count(pipeline->cb_in);
}