Beispiel #1
0
static lagopus_result_t
channel_id_eq(struct channel *chan, void *val) {
  struct channel_id_vars *v = val;

  if (channel_id_get(chan) == v->channel_id) {
    v->channel = chan;
    return 1;
  }

  return LAGOPUS_RESULT_OK;
}
/* Packetout packet receive. */
lagopus_result_t
ofp_packet_out_handle(struct channel *channel, struct pbuf *pbuf,
                      struct ofp_header *xid_header,
                      struct ofp_error *error) {
  lagopus_result_t res = LAGOPUS_RESULT_ANY_FAILURES;
  struct eventq_data *eventq_data = NULL;
  struct pbuf *data_pbuf = NULL;
  struct pbuf *req_pbuf = NULL;
  uint64_t dpid;
  uint16_t data_len = 0;

  /* check params */
  if (channel != NULL && pbuf != NULL &&
      xid_header != NULL && error != NULL) {
    dpid = channel_dpid_get(channel);

    /* create packet_out */
    eventq_data = malloc(sizeof(*eventq_data));
    if (eventq_data != NULL) {
      memset(eventq_data, 0, sizeof(*eventq_data));

      /* Init action-list. */
      TAILQ_INIT(&eventq_data->packet_out.action_list);
      eventq_data->packet_out.data = NULL;
      eventq_data->packet_out.req = NULL;

      /* decode. */
      if ((res = ofp_packet_out_decode(
                   pbuf, &(eventq_data->packet_out.ofp_packet_out))) !=
          LAGOPUS_RESULT_OK) {
        lagopus_msg_warning("packet_out decode error.\n");
        ofp_error_set(error, OFPET_BAD_REQUEST, OFPBRC_BAD_LEN);
        res = LAGOPUS_RESULT_OFP_ERROR;
      } else if ((res = ofp_action_parse(
                          pbuf,
                          eventq_data->packet_out.ofp_packet_out.actions_len,
                          &(eventq_data->packet_out.action_list), error)) !=
                 LAGOPUS_RESULT_OK) {
        lagopus_msg_warning("action_list decode error.\n");
      } else {                  /* decode success */
        /* set eventq_data members */
        eventq_data->type = LAGOPUS_EVENTQ_PACKET_OUT;
        eventq_data->free = ofp_packet_out_free;
        eventq_data->packet_out.channel_id = channel_id_get(channel);

        /* copy packet_out.data if needed */
        res = pbuf_length_get(pbuf, &data_len);
        if (res == LAGOPUS_RESULT_OK) {
          if (data_len != 0) {
            if (eventq_data->packet_out.ofp_packet_out.buffer_id ==
                OFP_NO_BUFFER) {
              /* alloc packet_out.data */
              data_pbuf = pbuf_alloc(data_len);
              if (data_pbuf != NULL) {
                res = pbuf_copy_with_length(data_pbuf, pbuf, data_len);

                if (res == LAGOPUS_RESULT_OK) {
                  eventq_data->packet_out.data = data_pbuf;
                } else {
                  lagopus_msg_warning("FAILED (%s).\n",
                                      lagopus_error_get_string(res));
                }
              } else {
                lagopus_msg_warning("Can't allocate data_pbuf.\n");
                res = LAGOPUS_RESULT_NO_MEMORY;
              }
            } else {
              lagopus_msg_warning("Not empty data filed in request(buffer_id = %x).\n",
                                  eventq_data->packet_out.ofp_packet_out.buffer_id);
              ofp_error_set(error, OFPET_BAD_REQUEST, OFPBRC_BUFFER_UNKNOWN);
              res = LAGOPUS_RESULT_OFP_ERROR;
            }
          } else {
            res = LAGOPUS_RESULT_OK;
          }

          /* Copy request for ofp_error. */
          if (res == LAGOPUS_RESULT_OK && error->req != NULL) {
            req_pbuf = pbuf_alloc(OFP_ERROR_MAX_SIZE);
            if (req_pbuf != NULL) {
              res = pbuf_copy(req_pbuf, error->req);

              if (res == LAGOPUS_RESULT_OK) {
                eventq_data->packet_out.req = req_pbuf;
              } else {
                lagopus_msg_warning("FAILED (%s).\n",
                                    lagopus_error_get_string(res));
              }
            } else {
              lagopus_msg_warning("Can't allocate data_pbuf.\n");
              res = LAGOPUS_RESULT_NO_MEMORY;
            }
          }

          if (res == LAGOPUS_RESULT_OK) {
            /* dump trace.*/
            packet_out_trace(&eventq_data->packet_out.ofp_packet_out,
                             &eventq_data->packet_out.action_list);

            /* send to DataPlane */
            res = ofp_handler_event_dataq_put(dpid, eventq_data);
            if (res != LAGOPUS_RESULT_OK) {
              lagopus_msg_warning("FAILED (%s).\n",
                                  lagopus_error_get_string(res));
            }
          }
        } else {
          lagopus_msg_warning("FAILED (%s).\n",
                              lagopus_error_get_string(res));
        }
      }

      if (res != LAGOPUS_RESULT_OK && eventq_data != NULL) {
        ofp_packet_out_free(eventq_data);
      }
    } else {
      /* channel_pbuf_list_get returns NULL */
      res = LAGOPUS_RESULT_NO_MEMORY;
    }
  } else {
    /* params are NULL */
    res = LAGOPUS_RESULT_INVALID_ARGS;
  }

  return res;
}
Beispiel #3
0
void
test_channel_tcp(void) {
  int sock4, sock6;
  socklen_t size;
  struct sockaddr_in sin;
  lagopus_ip_address_t *addr4 = NULL;
  lagopus_ip_address_t *addr6 = NULL;
  struct channel_list  *chan_list ;
  struct channel *chan4, *chan6, *chan = NULL;
  lagopus_result_t ret;
  int cnt;

  printf("test_channel_tcp in\n");
  channel_mgr_initialize();
  ret = channel_mgr_channels_lookup_by_dpid(dpid, &chan_list );
  TEST_ASSERT_EQUAL(LAGOPUS_RESULT_NOT_FOUND, ret);
  TEST_ASSERT_EQUAL(NULL, chan_list );

  ret = lagopus_ip_address_create("127.0.0.1", true, &addr4);
  TEST_ASSERT_EQUAL(LAGOPUS_RESULT_OK, ret);
  ret = lagopus_ip_address_create("::1", false, &addr6);
  TEST_ASSERT_EQUAL(LAGOPUS_RESULT_OK, ret);

  ret = channel_mgr_channel_add(bridge_name, dpid, addr4);
  TEST_ASSERT_EQUAL(LAGOPUS_RESULT_OK, ret);
  ret = channel_mgr_channel_add(bridge_name, dpid, addr6);
  TEST_ASSERT_EQUAL(LAGOPUS_RESULT_OK, ret);

  ret = channel_mgr_channel_add(bridge_name, dpid, addr4);
  TEST_ASSERT_EQUAL(LAGOPUS_RESULT_ALREADY_EXISTS, ret);
  ret = channel_mgr_channel_lookup(bridge_name, addr4, &chan4);
  TEST_ASSERT_EQUAL(LAGOPUS_RESULT_OK, ret);
  TEST_ASSERT_EQUAL(0, channel_id_get(chan4));
  ret = channel_port_set(chan4, 10022);
  TEST_ASSERT_EQUAL(LAGOPUS_RESULT_OK, ret);
  ret = channel_local_port_set(chan4, 20022);
  TEST_ASSERT_EQUAL(LAGOPUS_RESULT_OK, ret);
  ret = channel_local_addr_set(chan4, addr4);
  TEST_ASSERT_EQUAL(LAGOPUS_RESULT_OK, ret);

  ret = channel_mgr_channel_add(bridge_name, dpid, addr6);
  TEST_ASSERT_EQUAL(LAGOPUS_RESULT_ALREADY_EXISTS, ret);
  ret = channel_mgr_channel_lookup(bridge_name, addr6, &chan6);
  TEST_ASSERT_EQUAL(1, channel_id_get(chan6));
  TEST_ASSERT_EQUAL(LAGOPUS_RESULT_OK, ret);
  ret = channel_port_set(chan6, 10023);
  TEST_ASSERT_EQUAL(LAGOPUS_RESULT_OK, ret);
  ret = channel_local_port_set(chan6, 20023);
  TEST_ASSERT_EQUAL(LAGOPUS_RESULT_OK, ret);
  ret = channel_local_addr_set(chan6, addr6);
  TEST_ASSERT_EQUAL(LAGOPUS_RESULT_OK, ret);
  ret = channel_mgr_channel_lookup_by_channel_id(dpid, 1, &chan);
  TEST_ASSERT_EQUAL(LAGOPUS_RESULT_OK, ret);
  TEST_ASSERT_NOT_EQUAL(NULL, chan);

  ret = channel_mgr_channel_lookup_by_channel_id(dpid, 9999, &chan);
  TEST_ASSERT_EQUAL(LAGOPUS_RESULT_NOT_FOUND, ret);
  TEST_ASSERT_EQUAL(NULL, chan);

  cnt = 0;
  ret = channel_mgr_channels_lookup_by_dpid(dpid, &chan_list );
  TEST_ASSERT_EQUAL(LAGOPUS_RESULT_OK, ret);
  ret = channel_list_iterate(chan_list , channel_count, &cnt);
  TEST_ASSERT_EQUAL(LAGOPUS_RESULT_OK, ret);
  TEST_ASSERT_EQUAL(2, cnt);

  cnt = 0;
  ret = channel_mgr_dpid_iterate(dpid, channel_count, &cnt);
  TEST_ASSERT_EQUAL(LAGOPUS_RESULT_OK, ret);
  TEST_ASSERT_EQUAL(2, cnt);

  run = true;
  size = sizeof(sin);
  printf("accept in\n");
  sock4 = accept(s4, (struct sockaddr *)&sin, &size);
  TEST_ASSERT_NOT_EQUAL(-1, sock4);

  sock6 = accept(s6, (struct sockaddr *)&sin, &size);
  TEST_ASSERT_NOT_EQUAL(-1, sock6);


  ret = channel_mgr_channel_lookup(bridge_name, addr4, &chan4);
  TEST_ASSERT_EQUAL(LAGOPUS_RESULT_OK, ret);

  channel_refs_get(chan4);

  ret = channel_mgr_channel_delete(bridge_name, addr4);
  TEST_ASSERT_EQUAL(LAGOPUS_RESULT_OK, ret);

  channel_refs_put(chan4);
  ret = channel_mgr_channel_delete(bridge_name, addr4);

  TEST_ASSERT_EQUAL(LAGOPUS_RESULT_OK, ret);

  ret = channel_mgr_channel_lookup(bridge_name, addr4, &chan4);
  TEST_ASSERT_EQUAL(LAGOPUS_RESULT_NOT_FOUND, ret);

  ret = channel_mgr_channel_delete(bridge_name, addr6);
  TEST_ASSERT_EQUAL(LAGOPUS_RESULT_OK, ret);
  ret = channel_mgr_channel_lookup(bridge_name, addr6, &chan6);
  TEST_ASSERT_EQUAL(LAGOPUS_RESULT_NOT_FOUND, ret);

  TEST_ASSERT_FALSE(channel_mgr_has_alive_channel_by_dpid(dpid));

  ret = channel_mgr_event_upcall();
  TEST_ASSERT_EQUAL(LAGOPUS_RESULT_OK, ret);

  lagopus_ip_address_destroy(addr4);
  lagopus_ip_address_destroy(addr6);
  close(sock4);
  close(sock6);
}