Example #1
0
static lagopus_result_t
del_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 LAGOPUS_RESULT_NOT_FOUND;
    }
    rv = flowinfo->del_func(flowinfo, flow);
    if (flowinfo->nflow == 0) {
      flowinfo->destroy_func(flowinfo);
      self->nnext--;
      memmove(&self->next[i], &self->next[i + 1], (size_t)(self->nnext - i));
    }
  } else {
    rv = self->misc->del_func(self->misc, flow);
  }
  if (rv == LAGOPUS_RESULT_OK) {
    self->nflow--;
  }
  return rv;
}
Example #2
0
static struct flow *
find_flow_ipv4_dst(struct flowinfo *self, struct flow *flow) {
  struct flowinfo *flowinfo;
  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) {
    rv = lagopus_hashmap_find_no_lock(&self->hashmap, (void *)ipv4_dst,
                                      (void *)&flowinfo);
    if (rv != LAGOPUS_RESULT_OK) {
      return NULL;
    }
    return flowinfo->find_func(flowinfo, flow);
  } else {
    return self->misc->find_func(self->misc, flow);
  }
}
Example #3
0
static lagopus_result_t
add_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) {
      /* new node. */
      flowinfo = new_flowinfo_ipv4_dst();
      flowinfo->userdata = mask;
      self->next = realloc(self->next,
                           (unsigned long)(self->nnext + 1) *
                           sizeof(struct flowinfo *));
      self->next[self->nnext] = flowinfo;
      self->nnext++;
    }
    rv = flowinfo->add_func(flowinfo, flow);
  } else {
    rv = self->misc->add_func(self->misc, flow);
  }
  if (rv == LAGOPUS_RESULT_OK) {
    self->nflow++;
  }
  return rv;
}
Example #4
0
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);
  }
}
Example #5
0
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},
    .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;
  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) {
    rv = lagopus_hashmap_find_no_lock(&self->hashmap,
                                      (void *)ipv4_dst, (void *)&flowinfo);
    if (rv != LAGOPUS_RESULT_OK) {
      void *val;

      flowinfo = new_flowinfo_ipv4();
      val = flowinfo;
      lagopus_hashmap_add_no_lock(&self->hashmap, (void *)ipv4_dst,
                                  (void *)&val, false);
    }
    rv = flowinfo->add_func(flowinfo, flow);
    if (rv == LAGOPUS_RESULT_OK) {
      self->nflow++;
    }
  }
  return rv;
}

static lagopus_result_t
del_flow_ipv4_dst(struct flowinfo *self, struct flow *flow) {
  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) {
    struct flowinfo *flowinfo;

    rv = lagopus_hashmap_find_no_lock(&self->hashmap, (void *)ipv4_dst,
                                      (void *)&flowinfo);
    if (rv == LAGOPUS_RESULT_OK) {
      flowinfo->del_func(flowinfo, flow);
    }
    if (rv == LAGOPUS_RESULT_OK) {
      self->nflow--;
    }
  }
  return rv;
}