Ejemplo n.º 1
0
void
test_ofp_instruction_list_elem_free(void) {
  lagopus_result_t ret;
  struct pbuf *test_pbuf;
  struct instruction_list instruction_list;
  struct ofp_error error;

  /* instruction packet. */
  char nomal_data[] = "00 03 00 18 00 00 00 00"
                      "00 00 00 10 00 00 01 00 00 30 00 00 00 00 00 00";

  /* data */
  TAILQ_INIT(&instruction_list);
  create_packet(nomal_data, &test_pbuf);
  ret = ofp_instruction_parse(test_pbuf, &instruction_list, &error);
  TEST_ASSERT_EQUAL_MESSAGE(ret, LAGOPUS_RESULT_OK,
                            "ofp_instruction_parse(nomal) error.");

  TEST_ASSERT_EQUAL_MESSAGE(TAILQ_EMPTY(&instruction_list),
                            false, "not instruction list error.");

  /* call func. */
  ofp_instruction_list_elem_free(&instruction_list);

  TEST_ASSERT_EQUAL_MESSAGE(TAILQ_EMPTY(&instruction_list),
                            true, "instruction list error.");
}
Ejemplo n.º 2
0
void
test_ofp_flow_reply_create_01(void) {
  lagopus_result_t ret = LAGOPUS_RESULT_ANY_FAILURES;
  struct flow_stats *flow_stats = NULL;
  struct instruction *instruction = NULL;
  struct match *match = NULL;
  const char *require[1] = {
    "04 13 00 58 00 00 00 10 00 01 00 00 00 00 00 00 "
    "00 48 01 00 00 00 00 02 00 00 00 03 00 04 00 05 "
    "00 06 00 07 00 00 00 00 00 00 00 00 00 00 00 08 "
    "00 00 00 00 00 00 00 09 00 00 00 00 00 00 00 0a "
    "00 01 00 10 00 00 01 08 00 00 00 00 00 00 00 00 "
    "00 01 00 08 00 00 00 00"
  };

  TAILQ_INIT(&s_flow_stats_list);
  if ((flow_stats = s_flow_stats_alloc()) != NULL) {
    /* flow_stats = 48, match = 16, instruction = 8, sum = 72 */
    flow_stats->ofp.length = 48 + 16 + 8;
    flow_stats->ofp.table_id = 0x01;
    flow_stats->ofp.duration_sec = 0x02;
    flow_stats->ofp.duration_nsec = 0x03;
    flow_stats->ofp.priority = 0x04;
    flow_stats->ofp.idle_timeout = 0x05;
    flow_stats->ofp.hard_timeout = 0x06;
    flow_stats->ofp.flags = 0x07;
    flow_stats->ofp.cookie = 0x08;
    flow_stats->ofp.packet_count = 0x09;
    flow_stats->ofp.byte_count = 0x0a;
    if ((match = match_alloc(8)) != NULL) {
      match->oxm_class = 0x00;
      match->oxm_field = 0x01;
      match->oxm_length = 0x08;
      TAILQ_INSERT_TAIL(&(flow_stats->match_list), match, entry);
    }
    if ((instruction = instruction_alloc()) != NULL) {
      instruction->ofpit_goto_table.type = OFPIT_GOTO_TABLE;
      instruction->ofpit_goto_table.len = 0x08; /* action_list empty */
      instruction->ofpit_goto_table.table_id = 0x00;
      TAILQ_INSERT_TAIL(&(flow_stats->instruction_list), instruction, entry);
    }
    TAILQ_INSERT_TAIL(&s_flow_stats_list, flow_stats, entry);
  } else {
    TEST_FAIL_MESSAGE("allocation error.");
  }

  /* port 0 */
  ret = check_pbuf_list_packet_create(s_ofp_flow_reply_create_wrap, require, 1);
  TEST_ASSERT_EQUAL_MESSAGE(LAGOPUS_RESULT_OK, ret, "create port 0 error.");

  /* free */
  while ((flow_stats = TAILQ_FIRST(&s_flow_stats_list)) != NULL) {
    TAILQ_REMOVE(&s_flow_stats_list, flow_stats, entry);
    ofp_match_list_elem_free(&flow_stats->match_list);
    ofp_instruction_list_elem_free(&flow_stats->instruction_list);
    free(flow_stats);
  }
}
Ejemplo n.º 3
0
/* FlowMod packet receive. */
lagopus_result_t
ofp_flow_mod_handle(struct channel *channel, struct pbuf *pbuf,
                    struct ofp_header *xid_header,
                    struct ofp_error *error) {
  lagopus_result_t ret;
  uint64_t dpid;
  struct ofp_flow_mod flow_mod;
  struct match_list match_list;
  struct instruction_list instruction_list;

  if (channel != NULL && pbuf != NULL && xid_header != NULL) {
    /* Init lists. */
    TAILQ_INIT(&match_list);
    TAILQ_INIT(&instruction_list);

    /* Parse flow mod header. */
    ret = ofp_flow_mod_decode(pbuf, &flow_mod);

    if (ret == LAGOPUS_RESULT_OK) {
      ret = flow_mod_flags_check(flow_mod.flags, error);

      if (ret == LAGOPUS_RESULT_OK) {
        /* Parse matches. */
        ret = ofp_match_parse(channel, pbuf, &match_list, error);

        if (ret == LAGOPUS_RESULT_OK) {
          /* Parse instructions. */
          if (flow_mod.command == OFPFC_DELETE ||
              flow_mod.command == OFPFC_DELETE_STRICT) {
            /* skip pbuf. */
            ret = pbuf_forward(pbuf, pbuf_plen_get(pbuf));
            if (ret != LAGOPUS_RESULT_OK) {
              lagopus_msg_warning("FAILED (%s).\n",
                                  lagopus_error_get_string(ret));
            }
          } else {
            while (pbuf_plen_get(pbuf) > 0) {
              ret = ofp_instruction_parse(pbuf, &instruction_list, error);
              if (ret != LAGOPUS_RESULT_OK) {
                lagopus_msg_warning("FAILED (%s).\n",
                                    lagopus_error_get_string(ret));
                break;
              }
            }
          }

          if (ret == LAGOPUS_RESULT_OK) {
            /* trace. */
            flow_mod_trace(&flow_mod, &match_list, &instruction_list);

            /* Flow add, modify, delete. */
            dpid = channel_dpid_get(channel);
            switch (flow_mod.command) {
              case OFPFC_ADD:
                ret = ofp_flow_mod_check_add(dpid, &flow_mod,
                                             &match_list, &instruction_list,
                                             error);
                break;
              case OFPFC_MODIFY:
              case OFPFC_MODIFY_STRICT:
                ret = ofp_flow_mod_modify(dpid, &flow_mod,
                                          &match_list, &instruction_list,
                                          error);
                break;
              case OFPFC_DELETE:
              case OFPFC_DELETE_STRICT:
                ret = ofp_flow_mod_delete(dpid,
                                          &flow_mod, &match_list,
                                          error);
                break;
              default:
                ofp_error_set(error, OFPET_FLOW_MOD_FAILED, OFPFMFC_BAD_COMMAND);
                ret = LAGOPUS_RESULT_OFP_ERROR;
                break;
            }

            if (ret == LAGOPUS_RESULT_OFP_ERROR) {
              lagopus_msg_warning("OFP ERROR (%s).\n",
                                  lagopus_error_get_string(ret));
            }
          }
        } else {
          lagopus_msg_warning("FAILED (%s).\n", lagopus_error_get_string(ret));
        }
      } else {
        lagopus_msg_warning("FAILED (%s).\n",
                            lagopus_error_get_string(ret));
      }
    } else {
      lagopus_msg_warning("FAILED (%s).\n", lagopus_error_get_string(ret));
      ret = LAGOPUS_RESULT_OFP_ERROR;
      ofp_error_set(error, OFPET_BAD_REQUEST, OFPBRC_BAD_LEN);
    }

    /* free. */
    if (ret != LAGOPUS_RESULT_OK) {
      ofp_instruction_list_elem_free(&instruction_list);
      ofp_match_list_elem_free(&match_list);
    }
  } else {
    ret = LAGOPUS_RESULT_INVALID_ARGS;
  }

  return ret;
}
Ejemplo n.º 4
0
void
test_ofp_flow_reply_create_02(void) {
  lagopus_result_t ret = LAGOPUS_RESULT_ANY_FAILURES;
  struct flow_stats *flow_stats = NULL;
  struct match *match = NULL;
  const char *header_data[2] = {
    "04 13 ff b8 00 00 00 10 00 01 00 01 00 00 00 00 ",
    "04 13 00 58 00 00 00 10 00 01 00 00 00 00 00 00 "
  };
  const char *body_data[2] = {
    "00 48 01 00 00 00 00 02 00 00 00 03 00 04 00 05 "
    "00 06 00 07 00 00 00 00 00 00 00 00 00 00 00 08 "
    "00 00 00 00 00 00 00 09 00 00 00 00 00 00 00 0a "
    "00 01 00 18 00 00 01 10 00 00 00 00 00 00 00 00 "
    "00 00 00 00 00 00 00 00",
    "00 48 01 00 00 00 00 02 00 00 00 03 00 04 00 05 "
    "00 06 00 07 00 00 00 00 00 00 00 00 00 00 00 08 "
    "00 00 00 00 00 00 00 09 00 00 00 00 00 00 00 0a "
    "00 01 00 18 00 00 01 10 00 00 00 00 00 00 00 00 "
    "00 00 00 00 00 00 00 00"
  };
  size_t nums[2] = {909, 1};
  int i;

  /* data */
  TAILQ_INIT(&s_flow_stats_list);
  for (i = 0; i < 910; i++) {
    if ((flow_stats = s_flow_stats_alloc()) != NULL) {
      /* flow_stats = 48, match = 24, sum = 72 */
      flow_stats->ofp.length = 0;
      flow_stats->ofp.table_id = 0x01;
      flow_stats->ofp.duration_sec = 0x02;
      flow_stats->ofp.duration_nsec = 0x03;
      flow_stats->ofp.priority = 0x04;
      flow_stats->ofp.idle_timeout = 0x05;
      flow_stats->ofp.hard_timeout = 0x06;
      flow_stats->ofp.flags = 0x07;
      flow_stats->ofp.cookie = 0x08;
      flow_stats->ofp.packet_count = 0x09;
      flow_stats->ofp.byte_count = 0x0a;
      if ((match = match_alloc(16)) != NULL) {
        match->oxm_class = 0x00;
        match->oxm_field = 0x01;
        match->oxm_length = 0x10;
        TAILQ_INSERT_TAIL(&(flow_stats->match_list), match, entry);
      }
      TAILQ_INSERT_TAIL(&s_flow_stats_list, flow_stats, entry);
    } else {
      TEST_FAIL_MESSAGE("allocation error.");
    }
  }

  ret = check_pbuf_list_across_packet_create(s_ofp_flow_reply_create_wrap,
        header_data, body_data, nums, 2);
  TEST_ASSERT_EQUAL_MESSAGE(LAGOPUS_RESULT_OK, ret, "create port 0 error.");

  /* free */
  while ((flow_stats = TAILQ_FIRST(&s_flow_stats_list)) != NULL) {
    TAILQ_REMOVE(&s_flow_stats_list, flow_stats, entry);
    ofp_match_list_elem_free(&flow_stats->match_list);
    ofp_instruction_list_elem_free(&flow_stats->instruction_list);
    free(flow_stats);
  }
}