コード例 #1
0
ファイル: flowinfo_port.c プロジェクト: tidatida/lagopus
static struct flow *
match_flow_in_port(struct flowinfo *self, struct lagopus_packet *pkt,
                   int32_t *pri) {
  struct flowinfo *flowinfo;
  struct ptree_node *node;
  struct flow *flow, *alt_flow;

  flow = NULL;
  node = ptree_node_lookup(self->ptree,
                           (uint8_t *)&pkt->in_port->ofp_port.port_no, 32);
  if (node != NULL) {
    flowinfo = node->info;
    flow = flowinfo->match_func(flowinfo, pkt, pri);
    ptree_unlock_node(node);
  }
  alt_flow = self->misc->match_func(self->misc, pkt, pri);
  if (alt_flow != NULL) {
    flow = alt_flow;
  }
  return flow;
}
コード例 #2
0
ファイル: flowinfo_ipv4_dst.c プロジェクト: D-TOKIOKA/lagopus
static struct flow *
match_flow_ipv4_dst_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},
    .flow_type = 0,
    .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_ipv4_dst_mask(struct flowinfo *self, struct flow *flow) {
  struct flowinfo *flowinfo;
  uint32_t ipv4_dst, mask;
  lagopus_result_t rv;
  unsigned int i;

  rv = get_match_ipv4_dst(&flow->match_list, &ipv4_dst, &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_ipv4_dst(struct flowinfo *self, struct flow *flow) {
  struct flowinfo *flowinfo;
  struct ptree_node *node;
  uint32_t ipv4_dst, mask;
  lagopus_result_t rv;

  rv = get_match_ipv4_dst(&flow->match_list, &ipv4_dst, &mask);
  if (rv == LAGOPUS_RESULT_OK) {
    node = ptree_node_get(self->ptree, (uint8_t *)&ipv4_dst,
                          IPV4_DST_BITLEN);
    if (node->info == NULL) {
      /* new node. */
      node->info = new_flowinfo_ipv4();
    }
    flowinfo = node->info;
    rv = flowinfo->add_func(flowinfo, flow);
  } else {
    rv = self->misc->add_func(self->misc, flow);
  }
  if (rv == LAGOPUS_RESULT_OK) {
    self->nflow++;
  }
  return rv;
}

static lagopus_result_t
del_flow_ipv4_dst(struct flowinfo *self, struct flow *flow) {
  struct flowinfo *flowinfo;
  struct ptree_node *node;
  uint32_t ipv4_dst, mask;
  lagopus_result_t rv;

  rv = get_match_ipv4_dst(&flow->match_list, &ipv4_dst, &mask);
  if (rv == LAGOPUS_RESULT_OK) {
    node = ptree_node_lookup(self->ptree, (uint8_t *)&ipv4_dst,
                             IPV4_DST_BITLEN);
    if (node == NULL || node->info == NULL) {
      return LAGOPUS_RESULT_NOT_FOUND;
    }
    flowinfo = node->info;
    rv = flowinfo->del_func(flowinfo, flow);
  } else {
    rv = self->misc->del_func(self->misc, flow);
  }
  if (rv == LAGOPUS_RESULT_OK) {
    self->nflow--;
  }
  return rv;
}

static struct flow *
match_flow_ipv4_dst(struct flowinfo *self, struct lagopus_packet *pkt,
                    int32_t *pri) {
  struct flowinfo *flowinfo;
  struct ptree_node *node;
  uint32_t ipv4_dst;
  struct flow *flow;

  flow = NULL;
  ipv4_dst = (pkt->ipv4->ip_dst.s_addr & (uint32_t)self->userdata);
  node = ptree_node_lookup(self->ptree, (uint8_t *)&ipv4_dst, IPV4_DST_BITLEN);
  if (node != NULL) {
    flowinfo = node->info;
    flow = flowinfo->match_func(flowinfo, pkt, pri);
    ptree_unlock_node(node);
  }
  return flow;
}

static struct flow *
find_flow_ipv4_dst(struct flowinfo *self, struct flow *flow) {
  struct flowinfo *flowinfo;
  struct ptree_node *node;
  uint32_t ipv4_dst, mask;
  lagopus_result_t rv;

  rv = get_match_ipv4_dst(&flow->match_list, &ipv4_dst, &mask);
  if (rv == LAGOPUS_RESULT_OK) {
    node = ptree_node_get(self->ptree, (uint8_t *)&ipv4_dst,
                          IPV4_DST_BITLEN);
    if (node->info == NULL) {
      return NULL;
    }
    flowinfo = node->info;
    return flowinfo->find_func(flowinfo, flow);
  } else {
    return self->misc->find_func(self->misc, flow);
  }
}