diff options
Diffstat (limited to 'lib/route/cls/fw.c')
-rw-r--r-- | lib/route/cls/fw.c | 143 |
1 files changed, 36 insertions, 107 deletions
diff --git a/lib/route/cls/fw.c b/lib/route/cls/fw.c index 7ca7619..8cf25b9 100644 --- a/lib/route/cls/fw.c +++ b/lib/route/cls/fw.c @@ -6,7 +6,7 @@ * License as published by the Free Software Foundation version 2.1 * of the License. * - * Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch> + * Copyright (c) 2003-2009 Thomas Graf <tgraf@suug.ch> * Copyright (c) 2006 Petr Gotthard <petr.gotthard@siemens.com> * Copyright (c) 2006 Siemens AG Oesterreich */ @@ -32,19 +32,6 @@ #define FW_ATTR_INDEV 0x008 /** @endcond */ -static inline struct rtnl_fw *fw_cls(struct rtnl_cls *cls) -{ - return (struct rtnl_fw *) cls->c_subdata; -} - -static inline struct rtnl_fw *fw_alloc(struct rtnl_cls *cls) -{ - if (!cls->c_subdata) - cls->c_subdata = calloc(1, sizeof(struct rtnl_fw)); - - return fw_cls(cls); -} - static struct nla_policy fw_policy[TCA_FW_MAX+1] = { [TCA_FW_CLASSID] = { .type = NLA_U32 }, [TCA_FW_INDEV] = { .type = NLA_STRING, @@ -53,34 +40,30 @@ static struct nla_policy fw_policy[TCA_FW_MAX+1] = { static int fw_msg_parser(struct rtnl_cls *cls) { - int err; + struct rtnl_fw *f = rtnl_cls_data(cls); struct nlattr *tb[TCA_FW_MAX + 1]; - struct rtnl_fw *f; + int err; err = tca_parse(tb, TCA_FW_MAX, (struct rtnl_tca *) cls, fw_policy); if (err < 0) return err; - f = fw_alloc(cls); - if (!f) - goto errout_nomem; - if (tb[TCA_FW_CLASSID]) { f->cf_classid = nla_get_u32(tb[TCA_FW_CLASSID]); f->cf_mask |= FW_ATTR_CLASSID; } if (tb[TCA_FW_ACT]) { - f->cf_act = nla_get_data(tb[TCA_FW_ACT]); + f->cf_act = nl_data_alloc_attr(tb[TCA_FW_ACT]); if (!f->cf_act) - goto errout_nomem; + return -NLE_NOMEM; f->cf_mask |= FW_ATTR_ACTION; } if (tb[TCA_FW_POLICE]) { - f->cf_police = nla_get_data(tb[TCA_FW_POLICE]); + f->cf_police = nl_data_alloc_attr(tb[TCA_FW_POLICE]); if (!f->cf_police) - goto errout_nomem; + return -NLE_NOMEM; f->cf_mask |= FW_ATTR_POLICE; } @@ -90,120 +73,68 @@ static int fw_msg_parser(struct rtnl_cls *cls) } return 0; - -errout_nomem: - err = nl_errno(ENOMEM); - - return err; } static void fw_free_data(struct rtnl_cls *cls) { - struct rtnl_fw *f = fw_cls(cls); - - if (!f) - return; + struct rtnl_fw *f = rtnl_cls_data(cls); nl_data_free(f->cf_act); nl_data_free(f->cf_police); - - free(cls->c_subdata); } static int fw_clone(struct rtnl_cls *_dst, struct rtnl_cls *_src) { - struct rtnl_fw *dst, *src = fw_cls(_src); - - if (!src) - return 0; + struct rtnl_fw *dst = rtnl_cls_data(_dst); + struct rtnl_fw *src = rtnl_cls_data(_src); - dst = fw_alloc(_dst); - if (!dst) - return nl_errno(ENOMEM); - - if (src->cf_act) - if (!(dst->cf_act = nl_data_clone(src->cf_act))) - goto errout; + if (src->cf_act && !(dst->cf_act = nl_data_clone(src->cf_act))) + return -NLE_NOMEM; - if (src->cf_police) - if (!(dst->cf_police = nl_data_clone(src->cf_police))) - goto errout; + if (src->cf_police && !(dst->cf_police = nl_data_clone(src->cf_police))) + return -NLE_NOMEM; return 0; -errout: - return nl_get_errno(); } -static int fw_dump_brief(struct rtnl_cls *cls, struct nl_dump_params *p, - int line) +static void fw_dump_line(struct rtnl_cls *cls, struct nl_dump_params *p) { - struct rtnl_fw *f = fw_cls(cls); + struct rtnl_fw *f = rtnl_cls_data(cls); char buf[32]; - if (!f) - goto ignore; - if (f->cf_mask & FW_ATTR_CLASSID) - dp_dump(p, " target %s", + nl_dump(p, " target %s", rtnl_tc_handle2str(f->cf_classid, buf, sizeof(buf))); - -ignore: - return line; } -static int fw_dump_full(struct rtnl_cls *cls, struct nl_dump_params *p, - int line) +static void fw_dump_details(struct rtnl_cls *cls, struct nl_dump_params *p) { - struct rtnl_fw *f = fw_cls(cls); - - if (!f) - goto ignore; + struct rtnl_fw *f = rtnl_cls_data(cls); if (f->cf_mask & FW_ATTR_INDEV) - dp_dump(p, "indev %s ", f->cf_indev); - -ignore: - return line; + nl_dump(p, "indev %s ", f->cf_indev); } -static int fw_dump_stats(struct rtnl_cls *cls, struct nl_dump_params *p, - int line) +static int fw_get_opts(struct rtnl_cls *cls, struct nl_msg *msg) { - struct rtnl_fw *f = fw_cls(cls); - - if (!f) - goto ignore; - -ignore: - return line; -} - -static struct nl_msg *fw_get_opts(struct rtnl_cls *cls) -{ - struct rtnl_fw *f; - struct nl_msg *msg; + struct rtnl_fw *f = rtnl_cls_data(cls); - f = fw_cls(cls); - if (!f) - return NULL; - - msg = nlmsg_alloc(); - if (!msg) - return NULL; - if (f->cf_mask & FW_ATTR_CLASSID) - nla_put_u32(msg, TCA_FW_CLASSID, f->cf_classid); + NLA_PUT_U32(msg, TCA_FW_CLASSID, f->cf_classid); if (f->cf_mask & FW_ATTR_ACTION) - nla_put_data(msg, TCA_FW_ACT, f->cf_act); + NLA_PUT_DATA(msg, TCA_FW_ACT, f->cf_act); if (f->cf_mask & FW_ATTR_POLICE) - nla_put_data(msg, TCA_FW_POLICE, f->cf_police); + NLA_PUT_DATA(msg, TCA_FW_POLICE, f->cf_police); if (f->cf_mask & FW_ATTR_INDEV) - nla_put_string(msg, TCA_FW_INDEV, f->cf_indev); + NLA_PUT_STRING(msg, TCA_FW_INDEV, f->cf_indev); - return msg; + return 0; + +nla_put_failure: + return -NLE_NOMEM; } /** @@ -213,12 +144,8 @@ static struct nl_msg *fw_get_opts(struct rtnl_cls *cls) int rtnl_fw_set_classid(struct rtnl_cls *cls, uint32_t classid) { - struct rtnl_fw *f; + struct rtnl_fw *f = rtnl_cls_data(cls); - f = fw_alloc(cls); - if (!f) - return nl_errno(ENOMEM); - f->cf_classid = classid; f->cf_mask |= FW_ATTR_CLASSID; @@ -229,13 +156,15 @@ int rtnl_fw_set_classid(struct rtnl_cls *cls, uint32_t classid) static struct rtnl_cls_ops fw_ops = { .co_kind = "fw", + .co_size = sizeof(struct rtnl_fw), .co_msg_parser = fw_msg_parser, .co_free_data = fw_free_data, .co_clone = fw_clone, .co_get_opts = fw_get_opts, - .co_dump[NL_DUMP_BRIEF] = fw_dump_brief, - .co_dump[NL_DUMP_FULL] = fw_dump_full, - .co_dump[NL_DUMP_STATS] = fw_dump_stats, + .co_dump = { + [NL_DUMP_LINE] = fw_dump_line, + [NL_DUMP_DETAILS] = fw_dump_details, + }, }; static void __init fw_init(void) |