Пример #1
0
Файл: tf.c Проект: NetSys/sts
static struct list_res
rule_apply (const struct rule *r, const struct tf *tf, const struct res *in,
            bool append, uint32_t *app, int *napp)
{
  struct list_res res = {0};

  if (!r->out) app_add (r->idx, app, napp);
  if (!r->out || r->out == in->port) return res;

  struct hs hs;
  if (!r->match) hs_copy (&hs, &in->hs);
  else {
    if (!hs_isect_arr (&hs, &in->hs, DATA_ARR (r->match))) return res;
    if (r->deps) deps_diff (&hs, in->port, DEPS (tf, r->deps), tf, app, *napp);
    if (!hs_compact_m (&hs, r->mask ? DATA_ARR (r->mask) : NULL)) { hs_destroy (&hs); return res; }
    if (r->mask) hs_rewrite (&hs, DATA_ARR (r->mask), DATA_ARR (r->rewrite));
  }

  bool used_hs = false;
  uint32_t n, x;
  const uint32_t *a;
  if (r->out > 0) { n = 1; x = r->out; a = &x; }
  else {
    const struct ports *p = PORTS (tf, r->out);
    n = p->n; a = p->arr;
  }

  for (int i = 0; i < n; i++) {
    if (a[i] == in->port) continue;
    struct res *tmp;
    if (used_hs) tmp = res_extend (in, &hs, a[i], append);
    else {
      tmp = res_extend (in, NULL, a[i], append);
      tmp->hs = hs;
      used_hs = true;
    }
    res_rule_add (tmp, tf, r->idx);
    list_append (&res, tmp);
  }

  if (res.head) app_add (r->idx, app, napp);
  if (!used_hs) hs_destroy (&hs);
  return res;
}
Пример #2
0
struct list_res
rule_inv_apply (const struct tf *tf, const struct rule *r, const struct res *in,
		bool append)
{
  /* Given a rule `r` in a tf `tf`, apply the inverse of `r` on the input
     (headerspace,port) `in`. */
  struct list_res res = {0};

  // prune cases where rule outport doesn't include the current port
  if (r->out > 0 && r->out != in->port) return res;
  if (r->out < 0 && !port_match(in->port, r->out, tf)) return res;
  if (!r->out) return res;

  // set up inverse match and rewrite arrays
  array_t *inv_rw=0, *inv_mat=0;
  if (r->mask) { // rewrite rule
    inv_mat = rule_set_inv_mat (r, in->hs.len);
    inv_rw  = rule_set_inv_rw (r, in->hs.len);
  }
  else { // fwding and topology rules
    if (r->match) inv_mat = array_copy (DATA_ARR (r->match), in->hs.len);
  }

  struct hs hs;
  if (!r->match) hs_copy (&hs, &in->hs); // topology rule
  else { // fwding and rewrite rules
    if (!hs_isect_arr (&hs, &in->hs, inv_mat)) return res;
    if (r->mask) hs_rewrite (&hs, DATA_ARR (r->mask), inv_rw);
  }

  // there is a new hs result corresponding to each rule inport
  bool used_hs = port_append_res (&res, r, tf, in, r->in, append, &hs, true);

  if (inv_rw) array_free (inv_rw);
  if (inv_mat) array_free (inv_mat);
  if (!used_hs) hs_destroy (&hs);

  return res;
}
Пример #3
0
static struct list_res
rule_apply (const struct rule *r, const struct tf *tf, const struct res *in,
            bool append, uint32_t *app, int *napp)
{
  struct list_res res = {0};

  if (!r->out) app_add (r->idx, app, napp);
  if (!r->out || r->out == in->port) return res;

  struct hs hs;
  if (!r->match) hs_copy (&hs, &in->hs);
  else {
    if (!hs_isect_arr (&hs, &in->hs, DATA_ARR (r->match))) return res;
    if (r->deps) deps_diff (&hs, in->port, DEPS (tf, r->deps), tf, app, *napp);
    if (!hs_compact_m (&hs, r->mask ? DATA_ARR (r->mask) : NULL)) { hs_destroy (&hs); return res; }
    if (r->mask) hs_rewrite (&hs, DATA_ARR (r->mask), DATA_ARR (r->rewrite));
  }

  bool used_hs = port_append_res (&res, r, tf, in, r->out, append, &hs, false);

  if (res.head) app_add (r->idx, app, napp);
  if (!used_hs) hs_destroy (&hs);
  return res;
}