Logo Search packages:      
Sourcecode: libnl2 version File versions  Download package

cgroup.c

/*
 * lib/route/cls/cgroup.c     Control Groups Classifier
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License as published by the Free Software Foundation version 2.1
 *    of the License.
 *
 * Copyright (c) 2009 Thomas Graf <tgraf@suug.ch>
 */

/**
 * @ingroup cls_api
 * @defgroup cgroup Control Groups Classifier
 *
 * @{
 */

#include <netlink-local.h>
#include <netlink-tc.h>
#include <netlink/netlink.h>
#include <netlink/attr.h>
#include <netlink/utils.h>
#include <netlink/route/classifier.h>
#include <netlink/route/classifier-modules.h>
#include <netlink/route/cls/cgroup.h>
#include <netlink/route/cls/ematch.h>

/** @cond SKIP */
#define CGROUP_ATTR_EMATCH      0x001
/** @endcond */

00033 static struct nla_policy cgroup_policy[TCA_CGROUP_MAX+1] = {
      [TCA_CGROUP_EMATCHES]   = { .type = NLA_NESTED },
};

static void cgroup_free_data(struct rtnl_cls *cls)
{
      struct rtnl_cgroup *cg = rtnl_cls_data(cls);

      rtnl_ematch_tree_free(cg->cg_ematch);
}

static int cgroup_msg_parser(struct rtnl_cls *cls)
{
      struct rtnl_cgroup *cg = rtnl_cls_data(cls);
      struct nlattr *tb[TCA_CGROUP_MAX + 1];
      int err;

      err = tca_parse(tb, TCA_CGROUP_MAX, (struct rtnl_tca *) cls,
                  cgroup_policy);
      if (err < 0)
            return err;

      if (tb[TCA_CGROUP_EMATCHES]) {
            if ((err = rtnl_ematch_parse(tb[TCA_CGROUP_EMATCHES],
                                   &cg->cg_ematch)) < 0)
                  return err;
            cg->cg_mask |= CGROUP_ATTR_EMATCH;
      }

#if 0
      TODO:
      TCA_CGROUP_ACT,
      TCA_CGROUP_POLICE,
#endif

      return 0;
}

static void cgroup_dump_line(struct rtnl_cls *cls, struct nl_dump_params *p)
{
      struct rtnl_cgroup *cg = rtnl_cls_data(cls);

      if (cg->cg_mask & CGROUP_ATTR_EMATCH)
            nl_dump(p, " ematch");
      else
            nl_dump(p, " match-all");
}

static void cgroup_dump_details(struct rtnl_cls *cls, struct nl_dump_params *p)
{
      struct rtnl_cgroup *cg = rtnl_cls_data(cls);

      if (cg->cg_mask & CGROUP_ATTR_EMATCH) {
            nl_dump(p, "\n");
            nl_dump_line(p, "    ematch ");
            rtnl_ematch_tree_dump(cg->cg_ematch, p);
      }
}

/**
 * @name Attribute Modifications
 * @{
 */

int rtnl_cgroup_set_ematch(struct rtnl_cls *cls, struct rtnl_ematch_tree *tree)
{
      struct rtnl_cgroup *cg = rtnl_cls_data(cls);

      if (cg->cg_ematch) {
            rtnl_ematch_tree_free(cg->cg_ematch);
            cg->cg_mask &= ~CGROUP_ATTR_EMATCH;
      }

      cg->cg_ematch = tree;

      if (tree)
            cg->cg_mask |= CGROUP_ATTR_EMATCH;

      return 0;
}

struct rtnl_ematch_tree *rtnl_cgroup_get_ematch(struct rtnl_cls *cls)
{
      struct rtnl_cgroup *cg = rtnl_cls_data(cls);
      return cg->cg_ematch;
}

static struct rtnl_cls_ops cgroup_ops = {
      .co_kind          = "cgroup",
      .co_size          = sizeof(struct rtnl_cgroup),
      .co_msg_parser          = cgroup_msg_parser,
      .co_free_data           = cgroup_free_data,
      .co_dump = {
          [NL_DUMP_LINE]      = cgroup_dump_line,
          [NL_DUMP_DETAILS]   = cgroup_dump_details,
      },
};

static void __init cgroup_init(void)
{
      rtnl_cls_register(&cgroup_ops);
}

static void __exit cgroup_exit(void)
{
      rtnl_cls_unregister(&cgroup_ops);
}

/** @} */

Generated by  Doxygen 1.6.0   Back to index