Exemple #1
0
static void group_target(tree_t t, group_nets_ctx_t *ctx)
{
   switch (tree_kind(t)) {
   case T_REF:
      group_ref(t, ctx, 0, -1);
      break;

   case T_ARRAY_REF:
   case T_ARRAY_SLICE:
   case T_RECORD_REF:
      {
         type_t type = tree_type(t);
         if (!type_known_width(type))
            ungroup_name(t, ctx);
         else if (!group_name(t, ctx, 0, type_width(type)))
            ungroup_name(t, ctx);
      }
      break;

   case T_LITERAL:
   case T_OPEN:
      // Constant folding can cause this to appear
      break;

   case T_AGGREGATE:
      {
         const int nassocs = tree_assocs(t);
         for (int i = 0; i < nassocs; i++)
            group_target(tree_value(tree_assoc(t, i)), ctx);
      }
      break;

   default:
      fmt_loc(stdout, tree_loc(t));
      fatal_trace("Cannot handle tree kind %s in group_target",
                  tree_kind_str(tree_kind(t)));
   }
}
Exemple #2
0
static bool group_name(tree_t target, group_nets_ctx_t *ctx, int start, int n)
{
   switch (tree_kind(target)) {
   case T_REF:
      group_ref(target, ctx, start, n);
      return true;

   case T_ARRAY_REF:
      {
         tree_t value = tree_value(target);

         type_t type = tree_type(value);
         if (type_is_unconstrained(type))
            return false;

         int offset = 0;
         const int nparams = tree_params(target);
         for (int i = 0; i < nparams; i++) {
            tree_t index = tree_value(tree_param(target, i));
            const int stride = type_width(type_elem(type));

            if (tree_kind(index) != T_LITERAL) {
               if (i > 0)
                  return false;

               const int twidth = type_width(type);
               for (int j = 0; j < twidth; j += stride)
                  group_name(value, ctx, start + j, n);
               return true;
            }
            else {
               if (i > 0) {
                  range_t type_r = range_of(type, i);
                  int64_t low, high;
                  range_bounds(type_r, &low, &high);
                  offset *= high - low + 1;
               }

               offset += stride * rebase_index(type, i, assume_int(index));
            }
         }

         return group_name(value, ctx, start + offset, n);
      }

   case T_ARRAY_SLICE:
      {
         tree_t value = tree_value(target);
         type_t type  = tree_type(value);

         if (type_is_unconstrained(type))
            return false;    // Only in procedure

         range_t slice = tree_range(target, 0 );

         if (tree_kind(slice.left) != T_LITERAL
             || tree_kind(slice.right) != T_LITERAL)
            return false;

         int64_t low, high;
         range_bounds(slice, &low, &high);

         const int64_t low0 = rebase_index(type, 0, assume_int(slice.left));
         const int stride   = type_width(type_elem(type));

         return group_name(value, ctx, start + low0 * stride, n);
      }

   case T_RECORD_REF:
      {
         tree_t value = tree_value(target);
         type_t rec = tree_type(value);
         const int offset = record_field_to_net(rec, tree_ident(target));

         return group_name(value, ctx, start + offset, n);
      }

   case T_AGGREGATE:
   case T_LITERAL:
      // This can appear due to assignments to open ports with a
      // default value
      return true;

   default:
      fatal_at(tree_loc(target), "tree kind %s not yet supported for offset "
               "calculation", tree_kind_str(tree_kind(target)));
   }
}
Exemple #3
0
int conf_group_set(struct ipc_user *u, char *data, size_t len, __unused struct blob_buf *reply)
{
	conf conf = container_of(u, conf_s, ipc_users[CONF_IPC_GROUP_SET]);
	ifgroups igs = conf->igs;
	pim pim = conf->pim;
	struct blob_attr *tb[CONF_G_MAX];
	struct in6_addr grp, src;
	group g = NULL;
	source s = NULL;
	gsource gs = NULL;
	iface i = NULL;
	ifgroup ig = NULL;
	ifgsource ifgs = NULL;
	int join = 0, listen = 0, local = 0;
	char *str;
	int ret = 0;

	if(blobmsg_parse(conf_g_attrs, CONF_G_MAX, tb, data, len) ||
			!tb[CONF_G_GROUP] || !addr_pton(&grp, blobmsg_get_string(tb[CONF_G_GROUP])) ||
			!addr_is_multicast(&grp) ||
			(tb[CONF_G_SRC] && !addr_pton(&src, blobmsg_get_string(tb[CONF_G_SRC]))) ||
			(tb[CONF_G_LISTENER] && !tb[CONF_G_DEV]))
		return -EINVAL;

	if(tb[CONF_G_PIM]) {
		if(!(str = blobmsg_get_string(tb[CONF_G_PIM])))
			return -EINVAL;
		else if (!strcmp(str, "join"))
			join = PIM_JOIN;
		else if(!strcmp(str, "prune"))
			join = PIM_PRUNE;
		else if(!strcmp(str, "none"))
			join = PIM_NONE;
		else
			return -EINVAL;
	}

	if(tb[CONF_G_LISTENER]) {
		if(!(str = blobmsg_get_string(tb[CONF_G_LISTENER])))
			return -EINVAL;
		else if (!strcmp(str, "include"))
			listen = PIM_JOIN;
		else if(!strcmp(str, "exclude"))
			listen = PIM_PRUNE;
		else if(!strcmp(str, "none"))
			listen = PIM_NONE;
		else
			return -EINVAL;
	}

	if(tb[CONF_G_LOCAL]) {
		if(!(str = blobmsg_get_string(tb[CONF_G_LOCAL])))
			return -EINVAL;
		else if (!strcmp(str, "include"))
			local = PIM_JOIN;
		else if(!strcmp(str, "exclude"))
			local = PIM_PRUNE;
		else if(!strcmp(str, "none"))
			local = PIM_NONE;
		else
			return -EINVAL;
	}

	if((tb[CONF_G_LOCAL] && !tb[CONF_G_DEV]) ||
			(tb[CONF_G_LISTENER] && !tb[CONF_G_DEV]))
		return -EINVAL;

	if((tb[CONF_G_GROUP] && (!(g = group_get(igs, &grp, 1)) || !group_ref(g))) ||
			(tb[CONF_G_SRC] && ((!(s = source_get(igs, &src, 1)) || !group_ref(s)) ||
					(!(gs = gsource_get(g, s, 1)) || !gsource_ref(gs)))) ||
			(tb[CONF_G_DEV] && ((!(i = iface_get_byname(igs, blobmsg_get_string(tb[CONF_G_DEV]), 1)) || !iface_ref(i)) ||
							(!(ig = ifgroup_get(i, g, 1)) || !ifgroup_ref(ig)))) ||
							(ig && gs && (!(ifgs = ifgsource_get(ig, gs, 1)) || !ifgsource_ref(ifgs)))) {
		ret = -ENOMEM;
		goto out;
	}

	if(tb[CONF_G_PIM]) {
		if(gs) {
			L_INFO("Set configuration of gsource "GSOURCE_L" - pim_join_desired : %s", GSOURCE_LA(gs), PIM_STATE_STR(join));
			if(!gs->conf_join_desired)
				gsource_ref(gs);
			gs->conf_join_desired = join;
			pim_gsource_conf_changed(pim, gs);
			if(!gs->conf_join_desired)
				gsource_unref(gs);
		} else {
			L_INFO("Set configuration of group "GROUP_L" - pim_join_desired : %s", GROUP_LA(g), PIM_STATE_STR(join));
			if(!g->conf_join_desired)
				group_ref(g);
			g->conf_join_desired = join;
			pim_group_conf_changed(pim, g);
			if(!g->conf_join_desired)
				group_unref(g);
		}
	}

	if(tb[CONF_G_LOCAL]) {
		L_INFO("Set configuration of ifgroup "IFGROUP_L" - local_exclude : %d", IFGROUP_LA(ig), (local == PIM_PRUNE));
		if(!ig->conf_local_exclude)
			ifgroup_ref(ig);
		ig->conf_local_exclude = !!(local == PIM_PRUNE);
		pim_ifgroup_conf_changed(pim, ig);
		if(!ig->conf_local_exclude)
			ifgroup_unref(ig);
	}

	if (tb[CONF_G_LISTENER]) {
		if(ifgs) {
			listener_update_G_S(ifgs, LISTENER_CONF, listen == PIM_JOIN, listen == PIM_PRUNE);
		} else {
			listener_update_G(ig, LISTENER_CONF, listen == PIM_PRUNE);
		}
	}

out:
	if(ifgs)
		ifgsource_unref(ifgs);
	if(gs)
		gsource_unref(gs);
	if(ig)
		ifgroup_unref(ig);
	if(g)
		group_unref(g);
	if(s)
		source_unref(s);
	if(i)
		iface_unref(i);
	return ret;
}