コード例 #1
0
ファイル: datapath_test.c プロジェクト: D-TOKIOKA/lagopus
void
test_lagopus_match_and_action(void) {
  struct action_list action_list;
  struct dpmgr *my_dpmgr;
  struct bridge *bridge;
  struct table *table;
  struct action *action;
  struct ofp_action_output *action_set;
  struct port nport, *port;
  struct lagopus_packet pkt;
  OS_MBUF *m;

  /* setup bridge and port */
  my_dpmgr = dpmgr_alloc();
  dpmgr_bridge_add(my_dpmgr, "br0", 0);

  nport.type = LAGOPUS_PORT_TYPE_NULL; /* for test */
  nport.ifindex = 0;
  nport.ofp_port.hw_addr[0] = 1;
  dpmgr_port_add(my_dpmgr, &nport);
  nport.ifindex = 1;
  dpmgr_port_add(my_dpmgr, &nport);

  dpmgr_bridge_port_add(my_dpmgr, "br0", 0, 1);
  dpmgr_bridge_port_add(my_dpmgr, "br0", 1, 2);

  bridge = dpmgr_bridge_lookup(my_dpmgr, "br0");
  TEST_ASSERT_NOT_NULL(bridge);

  flowdb_switch_mode_set(bridge->flowdb, SWITCH_MODE_OPENFLOW);
  table = table_get(bridge->flowdb, 0);
  table->userdata = new_flowinfo_eth_type();

  TAILQ_INIT(&action_list);
  action = calloc(1, sizeof(*action) + 64);
  action_set = (struct ofp_action_output *)&action->ofpat;
  action_set->type = OFPAT_OUTPUT;
  lagopus_set_action_function(action);
  TAILQ_INSERT_TAIL(&action_list, action, entry);

  m = calloc(1, sizeof(*m));
  TEST_ASSERT_NOT_NULL_MESSAGE(m, "calloc error.");
  m->data = &m->dat[128];
  m->refcnt = 2;

  port = port_lookup(bridge->ports, 1);
  TEST_ASSERT_NOT_NULL(port);
  lagopus_set_in_port(&pkt, port);
  TEST_ASSERT_EQUAL(pkt.in_port, port);
  TEST_ASSERT_EQUAL(pkt.in_port->bridge, bridge);
  pkt.table_id = 0;
  lagopus_packet_init(&pkt, m);
  lagopus_match_and_action(&pkt);
  TEST_ASSERT_EQUAL_MESSAGE(m->refcnt, 1,
                            "match_and_action refcnt error.");
  free(m);
  dpmgr_free(my_dpmgr);
}
コード例 #2
0
ファイル: flowinfo_metadata.c プロジェクト: lagopus/lagopus
struct flowinfo *
new_flowinfo_metadata_mask(void) {
  struct flowinfo *self;

  self = calloc(1, sizeof(struct flowinfo));
  if (self != NULL) {
    self->nflow = 0;
    self->nnext = 0;
    self->next = malloc(1);
    self->misc = new_flowinfo_eth_type();
    self->add_func = add_flow_metadata_mask;
    self->del_func = del_flow_metadata_mask;
    self->match_func = match_flow_metadata_mask;
    self->find_func = find_flow_metadata_mask;
    self->destroy_func = destroy_flowinfo_metadata_mask;
  }
  return self;
}
コード例 #3
0
void
test_lagopus_find_flow(void) {
    datastore_bridge_info_t info;
    struct bridge *bridge;
    struct port *port;
    struct port nport;
    struct lagopus_packet *pkt;
    struct table *table;
    struct flow *flow;
    OS_MBUF *m;

    /* setup bridge and port */
    memset(&info, 0, sizeof(info));
    info.fail_mode = DATASTORE_BRIDGE_FAIL_MODE_SECURE;
    TEST_ASSERT_EQUAL(dp_bridge_create("br0", &info), LAGOPUS_RESULT_OK);
    TEST_ASSERT_EQUAL(dp_port_create("port0"), LAGOPUS_RESULT_OK);
    TEST_ASSERT_EQUAL(dp_port_create("port1"), LAGOPUS_RESULT_OK);
    TEST_ASSERT_EQUAL(dp_bridge_port_set("br0", "port0", 1), LAGOPUS_RESULT_OK);
    TEST_ASSERT_EQUAL(dp_bridge_port_set("br0", "port1", 2), LAGOPUS_RESULT_OK);

    pkt = alloc_lagopus_packet();
    TEST_ASSERT_NOT_NULL_MESSAGE(pkt, "lagopus_alloc_packet error.");
    m = pkt->mbuf;
    OS_M_APPEND(m, 64);
    m->refcnt = 2;

    bridge = dp_bridge_lookup("br0");
    TEST_ASSERT_NOT_NULL(bridge);
    lagopus_packet_init(pkt, m, port_lookup(&bridge->ports, 1));
    table = flowdb_get_table(pkt->in_port->bridge->flowdb, 0);
    table->userdata = new_flowinfo_eth_type();
    flow = lagopus_find_flow(pkt, table);
    TEST_ASSERT_EQUAL_MESSAGE(table->lookup_count, 0,
                              "lookup_count(misc) error.");
    TEST_ASSERT_NULL_MESSAGE(flow,
                             "flow(misc) error.");
    OS_MTOD(m, uint8_t *)[14] = 0x08;
    OS_MTOD(m, uint8_t *)[15] = 0x06;
    lagopus_packet_init(pkt, m, &port);
    flow = lagopus_find_flow(pkt, table);
    TEST_ASSERT_EQUAL_MESSAGE(table->lookup_count, 0,
                              "lookup_count(arp) error.");
    TEST_ASSERT_NULL_MESSAGE(flow,
                             "flow(arp) error.");
    OS_MTOD(m, uint8_t *)[14] = 0x08;
    OS_MTOD(m, uint8_t *)[15] = 0x00;
    lagopus_packet_init(pkt, m, port_lookup(&bridge->ports, 1));
    flow = lagopus_find_flow(pkt, table);
    TEST_ASSERT_EQUAL_MESSAGE(table->lookup_count, 0,
                              "lookup_count(ipv4) error.");
    TEST_ASSERT_NULL_MESSAGE(flow,
                             "flow(ipv4) error.");
    OS_MTOD(m, uint8_t *)[14] = 0x86;
    OS_MTOD(m, uint8_t *)[15] = 0xdd;
    OS_MTOD(m, uint8_t *)[20] = IPPROTO_TCP;
    lagopus_packet_init(pkt, m, port_lookup(&bridge->ports, 1));
    flow = lagopus_find_flow(pkt, table);
    TEST_ASSERT_EQUAL_MESSAGE(table->lookup_count, 0,
                              "lookup_count(ipv6) error.");
    TEST_ASSERT_NULL_MESSAGE(flow,
                             "flow(ipv6) error.");
    OS_MTOD(m, uint8_t *)[14] = 0x88;
    OS_MTOD(m, uint8_t *)[15] = 0x47;
    lagopus_packet_init(pkt, m, port_lookup(&bridge->ports, 1));
    flow = lagopus_find_flow(pkt, table);
    TEST_ASSERT_EQUAL_MESSAGE(table->lookup_count, 0,
                              "lookup_count(mpls) error.");
    TEST_ASSERT_NULL_MESSAGE(flow,
                             "flow(mpls) error.");
    OS_MTOD(m, uint8_t *)[14] = 0x88;
    OS_MTOD(m, uint8_t *)[15] = 0x48;
    lagopus_packet_init(pkt, m, port_lookup(&bridge->ports, 1));
    flow = lagopus_find_flow(pkt, table);
    TEST_ASSERT_EQUAL_MESSAGE(table->lookup_count, 0,
                              "lookup_count(mpls-mc) error.");
    TEST_ASSERT_NULL_MESSAGE(flow,
                             "flow(mpls-mc) error.");
    OS_MTOD(m, uint8_t *)[14] = 0x88;
    OS_MTOD(m, uint8_t *)[15] = 0xe7;
    lagopus_packet_init(pkt, m, port_lookup(&bridge->ports, 1));
    flow = lagopus_find_flow(pkt, table);
    TEST_ASSERT_EQUAL_MESSAGE(table->lookup_count, 0,
                              "lookup_count(pbb) error.");
    TEST_ASSERT_NULL_MESSAGE(flow,
                             "flow(pbb) error.");
}
コード例 #4
0
ファイル: flowinfo_metadata.c プロジェクト: lagopus/lagopus
static struct flow *
match_flow_metadata_mask(struct flowinfo *self, struct lagopus_packet *pkt,
                         int32_t *pri) {
  struct flowinfo *flowinfo;
  struct flow *flow[self->nnext], *matched, *alt_flow;
  struct flow mismatched = {
    .priority = 0,
    .flags = 0,
    .idle_timeout = 0,
    .hard_timeout = 0,
    .match_list = {NULL, NULL},
    .instruction_list = {NULL, NULL},
    .field_bits = 0
  };
  unsigned int i;

  matched = &mismatched;
  //#pragma omp parallel for
  for (i = 0; i < self->nnext; i++) {
    flowinfo = self->next[i];
    flow[i] = flowinfo->match_func(flowinfo, pkt, pri);
  }
  for (i = 0; i < self->nnext; i++) {
    if (flow[i] != NULL && flow[i]->priority > matched->priority) {
      matched = flow[i];
    }
  }
  alt_flow = self->misc->match_func(self->misc, pkt, pri);
  if (alt_flow != NULL) {
    matched = alt_flow;
  }
  if (matched == &mismatched) {
    matched = NULL;
  }
  return matched;
}

static struct flow *
find_flow_metadata_mask(struct flowinfo *self, struct flow *flow) {
  struct flowinfo *flowinfo;
  uint64_t metadata, mask;
  lagopus_result_t rv;
  unsigned int i;

  rv = get_match_metadata(&flow->match_list, &metadata, &mask);
  if (rv == LAGOPUS_RESULT_OK) {
    rv = LAGOPUS_RESULT_NOT_FOUND;
    for (i = 0; i < self->nnext; i++) {
      if (self->next[i]->userdata == mask) {
        flowinfo = self->next[i];
        rv = LAGOPUS_RESULT_OK;
        break;
      }
    }
    if (rv == LAGOPUS_RESULT_NOT_FOUND) {
      return NULL;
    }
  } else {
    flowinfo = self->misc;
  }
  return flowinfo->find_func(flowinfo, flow);
}

static lagopus_result_t
add_flow_metadata(struct flowinfo *self, struct flow *flow) {
  struct flowinfo *flowinfo;
  uint64_t metadata, mask;
  lagopus_result_t rv;

  rv = get_match_metadata(&flow->match_list, &metadata, &mask);
  if (rv == LAGOPUS_RESULT_OK) {
    rv = lagopus_hashmap_find_no_lock(&self->hashmap,
                                      (void *)metadata, (void *)&flowinfo);
    if (rv != LAGOPUS_RESULT_OK) {
      void *val;

      flowinfo = new_flowinfo_eth_type();
      val = flowinfo;
      rv = lagopus_hashmap_add_no_lock(&self->hashmap, (void *)metadata,
                                       (void *)&val, false);
      if (rv != LAGOPUS_RESULT_OK) {
        goto out;
      }
    }
    rv = flowinfo->add_func(flowinfo, flow);
    if (rv == LAGOPUS_RESULT_OK) {
      self->nflow++;
    }
  }
out:
  return rv;
}

static lagopus_result_t
del_flow_metadata(struct flowinfo *self, struct flow *flow) {
  uint64_t metadata, mask;
  lagopus_result_t rv;

  rv = get_match_metadata(&flow->match_list, &metadata, &mask);
  if (rv == LAGOPUS_RESULT_OK) {
    struct flowinfo *flowinfo;

    rv = lagopus_hashmap_find_no_lock(&self->hashmap, (void *)metadata,
                                      (void *)&flowinfo);
    if (rv == LAGOPUS_RESULT_OK) {
      rv = flowinfo->del_func(flowinfo, flow);
    }
    if (rv == LAGOPUS_RESULT_OK) {
      self->nflow--;
    }
  }
  return rv;
}
コード例 #5
0
ファイル: match_mpls_test.c プロジェクト: D-TOKIOKA/lagopus
void
test_match_flow_mpls(void) {
  struct lagopus_packet pkt;
  struct flowinfo *flowinfo;
  struct flow *flow;
  struct port port;
  OS_MBUF *m;
  int32_t prio;
  int i, nflow;

  /* prepare packet */
  pkt.in_port = &port;
  m = calloc(1, sizeof(*m));
  TEST_ASSERT_NOT_NULL_MESSAGE(m, "calloc error.");
  m->data = &m->dat[128];
  OS_M_PKTLEN(m) = 64;

  /* prepare flow table */
  test_flow[0] = allocate_test_flow(10 * sizeof(struct match));
  test_flow[0]->priority = 3;
  add_match(&test_flow[0]->match_list, 2, OFPXMT_OFB_ETH_TYPE << 1,
            0x88, 0x47);
  add_match(&test_flow[0]->match_list, 4, OFPXMT_OFB_MPLS_LABEL << 1,
            0x00, 0x00, 0x00, 0x01);

  test_flow[1] = allocate_test_flow(10 * sizeof(struct match));
  test_flow[1]->priority = 2;
  FLOW_ADD_PORT_MATCH(test_flow[1], 2);

  test_flow[2] = allocate_test_flow(10 * sizeof(struct match));
  test_flow[2]->priority = 1;
  FLOW_ADD_PORT_MATCH(test_flow[2], 3);

  /* create flowinfo */
  flowinfo = new_flowinfo_eth_type();
  nflow = sizeof(test_flow) / sizeof(test_flow[0]);
  for (i = 0; i < nflow; i++) {
    flowinfo->add_func(flowinfo, test_flow[i]);
  }

  /* test */
  prio = 0;
  m->data[12] = 0x88;
  m->data[13] = 0x47;

  m->data[14] = 0xff;
  m->data[15] = 0xff;
  m->data[16] = 0xff;
  m->data[17] = 0xff;
  lagopus_packet_init(&pkt, m);
  flow = flowinfo->match_func(flowinfo, &pkt, &prio);
  TEST_ASSERT_NULL_MESSAGE(flow, "match_flow_mpls mismatch error");
  m->data[14] = 0x00;
  m->data[15] = 0x00;
  m->data[16] = 0x1f;
  m->data[17] = 0xff;
  flow = flowinfo->match_func(flowinfo, &pkt, &prio);
  TEST_ASSERT_EQUAL_MESSAGE(flow, test_flow[0],
                            "match_flow_mpls match flow error.");
  TEST_ASSERT_EQUAL_MESSAGE(prio, 3,
                            "match_flow_mpls match prio error.");
}