예제 #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.");
}
예제 #2
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;
}