示例#1
0
文件: res.c 项目: 15ramky/pyretic
struct list_res
res_walk_parents (const struct res *out, const struct hs *hs, int in_port,
		  array_t* out_arr)
{
  struct res *curr_res = (struct res*) out;
  struct list_res currq = {0};

  // set up initial result to start inversion
  struct hs int_hs;
  hs_isect_arr (&int_hs, &out->hs, out_arr);
  list_append (&currq, res_extend (out, &int_hs, out->port, true));

  struct res *cur;

  while (curr_res) {
    if (curr_res->rules.cur) {
      for (int i = curr_res->rules.cur - 1; i >= 0; i--) {
	struct list_res nextq = {0};
	struct res_rule r = curr_res->rules.arr[i];
	while ((cur = currq.head)) {
	  list_pop (&currq);
	  struct list_res tmp = rule_inv_apply (r.tf_tf, r.tf_rule, cur, false);
	  list_concat (&nextq, &tmp);
	  res_free (cur);
	} // for each current result from rule inversion
	currq = nextq;
      } // for each rule
    }
    else return currq;

    // set (hs,port) which the inverted (hs,port) results must intersect
    struct res *parent = curr_res->parent;
    struct hs *next_hs = hs_create (curr_res->hs.len);
    int next_port;
    if (parent) {
      hs_copy (next_hs, &parent->hs);
      next_port = parent->port;
    }
    else {
      hs_copy (next_hs, hs);
      next_port = in_port;
    }

    // Intersect the results in `currq` with the target (hs,port)
    struct list_res nextq = {0};
    while ((cur = currq.head)) {
      list_pop (&currq);
      struct hs *new_hs = hs_isect_a (&cur->hs, next_hs);
      if (cur->port == next_port && new_hs)
	list_append (&nextq, res_extend (cur, new_hs, next_port, false));
      else
	res_free (cur);
    }
    currq = nextq;
    curr_res = parent;
  }

  return currq;
}
示例#2
0
文件: app.c 项目: MurphyMc/sts
struct list_res
reachability (const struct hs *hs, uint32_t port, const uint32_t *out, int nout)
{
  struct res *in = res_create (data_file->stages + 1);
  struct list_res res = {0};
  hs_copy (&in->hs, hs);
  in->port = port;
  list_append (&queues[ntf_get_sw (in->port)], in);

  int n = data_file->ntfs - 1;
  struct tdata data[n];
  memset (data, 0, sizeof data);

  g_out = out;
  g_nout = nout;

  for (int i = 0; i < n; i++) {
    struct tdata *p = &data[i];
    p->sw = i;
    pthread_create (&p->tid, NULL, reach_thread, p);
  }
  for (int i = 0; i < n; i++) {
    pthread_join (data[i].tid, NULL);
    list_concat (&res, &data[i].res);
  }

  return res;
}
示例#3
0
文件: hs.c 项目: NetSys/sts
struct hs *
hs_copy_a (const struct hs *hs)
{
  struct hs *res = xmalloc (sizeof *res);
  hs_copy (res, hs);
  return res;
}
示例#4
0
文件: app.c 项目: 15ramky/pyretic
void
app_add_in (const struct hs *hs, uint32_t port)
{
  struct res *in = res_create (data_file->stages + 1);
  hs_copy (&in->hs, hs);
  in->port = port;
  list_append (&queues[ntf_get_sw (in->port)], in);
}
示例#5
0
文件: hs.c 项目: NetSys/sts
void
hs_minus (struct hs *a, const struct hs *b)
{
  assert (a->len == b->len);
  struct hs tmp;
  hs_copy (&tmp, b);
  hs_cmpl (&tmp);
  hs_isect (a, &tmp);
  hs_destroy (&tmp);
  hs_compact (a);
}
示例#6
0
文件: res.c 项目: 15ramky/pyretic
struct res *
res_extend (const struct res *src, const struct hs *hs, uint32_t port,
            bool append)
{
  struct res *res = res_create (src->rules.n);
  if (hs) hs_copy (&res->hs, hs);
  res->port = port;
  if (append) {
    res->rules.cur = src->rules.cur;
    memcpy (res->rules.arr, src->rules.arr, res->rules.cur * sizeof *res->rules.arr);
  }
  return res;
}
示例#7
0
文件: tf.c 项目: 15ramky/pyretic
static bool
port_append_res (struct list_res *res, const struct rule *r,
		 const struct tf *tf, const struct res *in, int32_t ports,
		 bool append, const struct hs *hs, bool inv_remove_deps)
{
  /* Create new result containing headerspace `hs` for each port in `ports`. */
  bool used_hs = false;
  struct hs *new_hs;
  uint32_t n, x;
  const uint32_t *a;
  if (ports > 0) { n = 1; x = ports; a = &x; }
  else {
    const struct ports *p = PORTS (tf, ports);
    n = p->n; a = p->arr;
  }

  for (int i = 0; i < n; i++) {
    if (a[i] == in->port) continue;

    if (inv_remove_deps) {
      /* For inversion, also remove dependencies for each input port of the
	 inverted rule. */
      new_hs = hs_create (hs->len);
      hs_copy (new_hs, hs);
      if (r->deps) deps_diff_inv (new_hs, a[i], DEPS (tf, r->deps), tf);

      if (!hs_compact_m (new_hs, r->mask ? DATA_ARR (r->mask) : NULL)) { hs_destroy(new_hs); continue; }
    }
    else new_hs = (struct hs*) hs;

    // now *new_hs has the latest hs at this port
    struct res *tmp;
    if (! inv_remove_deps) {
      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;
      }
    }
    else {
      tmp = res_extend (in, NULL, a[i], append);
      tmp->hs = *new_hs;
    }
    res_rule_add (tmp, tf, r->idx, r);
    list_append (res, tmp);
  }

  return used_hs;
}
示例#8
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;
}
示例#9
0
文件: tf.c 项目: 15ramky/pyretic
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;
}
示例#10
0
文件: tf.c 项目: 15ramky/pyretic
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;
}