diff options
author | A C <bsderandrew@gmail.com> | 2012-05-25 19:45:45 (GMT) |
---|---|---|
committer | Thomas Graf <tgraf@redhat.com> | 2012-05-29 09:40:13 (GMT) |
commit | 9bb30a5e801fff2333d9b847be42294aa2e34e06 (patch) | |
tree | 73b22d39bb6ab4080bd89e1a67c9b64f0a5e4c77 /lib/route | |
parent | ca883b61bc88498309afb82be9c8fa071febc741 (diff) | |
download | libnl-9bb30a5e801fff2333d9b847be42294aa2e34e06.zip libnl-9bb30a5e801fff2333d9b847be42294aa2e34e06.tar.gz libnl-9bb30a5e801fff2333d9b847be42294aa2e34e06.tar.bz2 |
add fwmark mask support
The fw classifier allows a mask to be set, which is necessary for some
complex shaping/firewall scenarios. The attached patch adds support
for it to libnl.
Diffstat (limited to 'lib/route')
-rw-r--r-- | lib/route/cls/fw.c | 31 |
1 files changed, 30 insertions, 1 deletions
diff --git a/lib/route/cls/fw.c b/lib/route/cls/fw.c index 11c9c67..d24779a 100644 --- a/lib/route/cls/fw.c +++ b/lib/route/cls/fw.c @@ -30,12 +30,14 @@ #define FW_ATTR_ACTION 0x002 #define FW_ATTR_POLICE 0x004 #define FW_ATTR_INDEV 0x008 +#define FW_ATTR_MASK 0x010 /** @endcond */ static struct nla_policy fw_policy[TCA_FW_MAX+1] = { [TCA_FW_CLASSID] = { .type = NLA_U32 }, [TCA_FW_INDEV] = { .type = NLA_STRING, .maxlen = IFNAMSIZ }, + [TCA_FW_MASK] = { .type = NLA_U32 }, }; static int fw_msg_parser(struct rtnl_tc *tc, void *data) @@ -72,6 +74,11 @@ static int fw_msg_parser(struct rtnl_tc *tc, void *data) f->cf_mask |= FW_ATTR_INDEV; } + if (tb[TCA_FW_MASK]) { + f->cf_fwmask = nla_get_u32(tb[TCA_FW_MASK]); + f->cf_mask |= FW_ATTR_MASK; + } + return 0; } @@ -101,12 +108,18 @@ static void fw_dump_line(struct rtnl_tc *tc, void *data, { struct rtnl_fw *f = data; - if (f && f->cf_mask & FW_ATTR_CLASSID) { + if (!f) + return; + + if (f->cf_mask & FW_ATTR_CLASSID) { char buf[32]; nl_dump(p, " target %s", rtnl_tc_handle2str(f->cf_classid, buf, sizeof(buf))); } + + if (f->cf_mask & FW_ATTR_MASK) + nl_dump(p, " mask 0x%x", f->cf_fwmask); } static void fw_dump_details(struct rtnl_tc *tc, void *data, @@ -137,6 +150,9 @@ static int fw_msg_fill(struct rtnl_tc *tc, void *data, struct nl_msg *msg) if (f->cf_mask & FW_ATTR_INDEV) NLA_PUT_STRING(msg, TCA_FW_INDEV, f->cf_indev); + if (f->cf_mask & FW_ATTR_MASK) + NLA_PUT_U32(msg, TCA_FW_MASK, f->cf_fwmask); + return 0; nla_put_failure: @@ -161,6 +177,19 @@ int rtnl_fw_set_classid(struct rtnl_cls *cls, uint32_t classid) return 0; } +int rtnl_fw_set_mask(struct rtnl_cls *cls, uint32_t mask) +{ + struct rtnl_fw *f; + + if (!(f = rtnl_tc_data(TC_CAST(cls)))) + return -NLE_NOMEM; + + f->cf_fwmask = mask; + f->cf_mask |= FW_ATTR_MASK; + + return 0; +} + /** @} */ static struct rtnl_tc_ops fw_ops = { |