route/cls: support 'match mark' u32 filters
Signed-off-by: Thomas Haller <thaller@redhat.com>
This commit is contained in:
parent
d65c32a720
commit
3844b15d73
3 changed files with 88 additions and 5 deletions
|
@ -528,6 +528,7 @@ struct rtnl_u32
|
|||
uint32_t cu_link;
|
||||
struct nl_data * cu_pcnt;
|
||||
struct nl_data * cu_selector;
|
||||
struct nl_data * cu_mark;
|
||||
struct rtnl_act* cu_act;
|
||||
struct nl_data * cu_police;
|
||||
char cu_indev[IFNAMSIZ];
|
||||
|
|
|
@ -30,6 +30,8 @@ extern int rtnl_u32_set_hashmask(struct rtnl_cls *, uint32_t, uint32_t);
|
|||
extern int rtnl_u32_set_cls_terminal(struct rtnl_cls *);
|
||||
|
||||
extern int rtnl_u32_set_flags(struct rtnl_cls *, int);
|
||||
extern int rtnl_u32_add_mark(struct rtnl_cls *, uint32_t, uint32_t);
|
||||
extern int rtnl_u32_del_mark(struct rtnl_cls *);
|
||||
extern int rtnl_u32_add_key(struct rtnl_cls *, uint32_t, uint32_t,
|
||||
int, int);
|
||||
extern int rtnl_u32_get_key(struct rtnl_cls *, uint8_t, uint32_t *, uint32_t *,
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
#define U32_ATTR_ACTION 0x040
|
||||
#define U32_ATTR_POLICE 0x080
|
||||
#define U32_ATTR_INDEV 0x100
|
||||
#define U32_ATTR_MARK 0x200
|
||||
/** @endcond */
|
||||
|
||||
static inline struct tc_u32_sel *u32_selector(struct rtnl_u32 *u)
|
||||
|
@ -53,6 +54,19 @@ static inline struct tc_u32_sel *u32_selector_alloc(struct rtnl_u32 *u)
|
|||
return u32_selector(u);
|
||||
}
|
||||
|
||||
static inline struct tc_u32_mark *u32_mark(struct rtnl_u32 *u)
|
||||
{
|
||||
return (struct tc_u32_mark *) u->cu_mark->d_data;
|
||||
}
|
||||
|
||||
static inline struct tc_u32_mark *u32_mark_alloc(struct rtnl_u32 *u)
|
||||
{
|
||||
if (!u->cu_mark)
|
||||
u->cu_mark = nl_data_alloc(NULL, sizeof(struct tc_u32_mark));
|
||||
|
||||
return u32_mark(u);
|
||||
}
|
||||
|
||||
static struct nla_policy u32_policy[TCA_U32_MAX+1] = {
|
||||
[TCA_U32_DIVISOR] = { .type = NLA_U32 },
|
||||
[TCA_U32_HASH] = { .type = NLA_U32 },
|
||||
|
@ -62,6 +76,7 @@ static struct nla_policy u32_policy[TCA_U32_MAX+1] = {
|
|||
.maxlen = IFNAMSIZ },
|
||||
[TCA_U32_SEL] = { .minlen = sizeof(struct tc_u32_sel) },
|
||||
[TCA_U32_PCNT] = { .minlen = sizeof(struct tc_u32_pcnt) },
|
||||
[TCA_U32_MARK] = { .minlen = sizeof(struct tc_u32_mark) }
|
||||
};
|
||||
|
||||
static int u32_msg_parser(struct rtnl_tc *tc, void *data)
|
||||
|
@ -86,6 +101,13 @@ static int u32_msg_parser(struct rtnl_tc *tc, void *data)
|
|||
u->cu_mask |= U32_ATTR_SELECTOR;
|
||||
}
|
||||
|
||||
if (tb[TCA_U32_MARK]) {
|
||||
u->cu_mark = nl_data_alloc_attr(tb[TCA_U32_MARK]);
|
||||
if (!u->cu_mark)
|
||||
goto errout_nomem;
|
||||
u->cu_mask |= U32_ATTR_MARK;
|
||||
}
|
||||
|
||||
if (tb[TCA_U32_HASH]) {
|
||||
u->cu_hash = nla_get_u32(tb[TCA_U32_HASH]);
|
||||
u->cu_mask |= U32_ATTR_HASH;
|
||||
|
@ -157,6 +179,7 @@ static void u32_free_data(struct rtnl_tc *tc, void *data)
|
|||
|
||||
if (u->cu_act)
|
||||
rtnl_act_put_all(&u->cu_act);
|
||||
nl_data_free(u->cu_mark);
|
||||
nl_data_free(u->cu_selector);
|
||||
nl_data_free(u->cu_police);
|
||||
nl_data_free(u->cu_pcnt);
|
||||
|
@ -170,6 +193,10 @@ static int u32_clone(void *_dst, void *_src)
|
|||
!(dst->cu_selector = nl_data_clone(src->cu_selector)))
|
||||
return -NLE_NOMEM;
|
||||
|
||||
if (src->cu_mark &&
|
||||
!(dst->cu_mark = nl_data_clone(src->cu_mark)))
|
||||
return -NLE_NOMEM;
|
||||
|
||||
if (src->cu_act) {
|
||||
if (!(dst->cu_act = rtnl_act_alloc()))
|
||||
return -NLE_NOMEM;
|
||||
|
@ -265,19 +292,28 @@ static void u32_dump_details(struct rtnl_tc *tc, void *data,
|
|||
struct nl_dump_params *p)
|
||||
{
|
||||
struct rtnl_u32 *u = data;
|
||||
struct tc_u32_sel *s;
|
||||
struct tc_u32_sel *s = NULL;
|
||||
struct tc_u32_mark *m;
|
||||
|
||||
if (!u)
|
||||
return;
|
||||
|
||||
if (!(u->cu_mask & U32_ATTR_SELECTOR)) {
|
||||
nl_dump(p, "no-selector\n");
|
||||
return;
|
||||
} else {
|
||||
s = u->cu_selector->d_data;
|
||||
nl_dump(p, "nkeys %u ", s->nkeys);
|
||||
}
|
||||
|
||||
s = u->cu_selector->d_data;
|
||||
if (!(u->cu_mask & U32_ATTR_MARK)) {
|
||||
nl_dump(p, "no-mark\n");
|
||||
} else {
|
||||
m = u->cu_mark->d_data;
|
||||
nl_dump(p, "mark 0x%u 0x%u\n", m->val, m->mask);
|
||||
}
|
||||
|
||||
nl_dump(p, "nkeys %u ", s->nkeys);
|
||||
if (!(u->cu_mask & U32_ATTR_SELECTOR) && !(u->cu_mask & U32_ATTR_MARK))
|
||||
return;
|
||||
|
||||
if (u->cu_mask & U32_ATTR_HASH)
|
||||
nl_dump(p, "ht key 0x%x hash 0x%u",
|
||||
|
@ -289,7 +325,9 @@ static void u32_dump_details(struct rtnl_tc *tc, void *data,
|
|||
if (u->cu_mask & U32_ATTR_INDEV)
|
||||
nl_dump(p, "indev %s ", u->cu_indev);
|
||||
|
||||
print_selector(p, s, u);
|
||||
if (u->cu_mask & U32_ATTR_SELECTOR)
|
||||
print_selector(p, s, u);
|
||||
|
||||
nl_dump(p, "\n");
|
||||
}
|
||||
|
||||
|
@ -330,6 +368,9 @@ static int u32_msg_fill(struct rtnl_tc *tc, void *data, struct nl_msg *msg)
|
|||
|
||||
if (u->cu_mask & U32_ATTR_SELECTOR)
|
||||
NLA_PUT_DATA(msg, TCA_U32_SEL, u->cu_selector);
|
||||
|
||||
if (u->cu_mask & U32_ATTR_MARK)
|
||||
NLA_PUT_DATA(msg, TCA_U32_MARK, u->cu_mark);
|
||||
|
||||
if (u->cu_mask & U32_ATTR_ACTION) {
|
||||
int err;
|
||||
|
@ -571,6 +612,45 @@ int rtnl_u32_add_key(struct rtnl_cls *cls, uint32_t val, uint32_t mask,
|
|||
return 0;
|
||||
}
|
||||
|
||||
int rtnl_u32_add_mark(struct rtnl_cls *cls, uint32_t val, uint32_t mask)
|
||||
{
|
||||
struct tc_u32_mark *mark;
|
||||
struct rtnl_u32 *u;
|
||||
|
||||
if (!(u = rtnl_tc_data(TC_CAST(cls))))
|
||||
return -NLE_NOMEM;
|
||||
|
||||
mark = u32_mark_alloc(u);
|
||||
if (!mark)
|
||||
return -NLE_NOMEM;
|
||||
|
||||
mark->mask = mask;
|
||||
mark->val = val;
|
||||
|
||||
u->cu_mask |= U32_ATTR_MARK;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rtnl_u32_del_mark(struct rtnl_cls *cls)
|
||||
{
|
||||
struct rtnl_u32 *u;
|
||||
|
||||
if (!(u = rtnl_tc_data(TC_CAST(cls))))
|
||||
return -NLE_NOMEM;
|
||||
|
||||
if (!(u->cu_mask))
|
||||
return -NLE_INVAL;
|
||||
|
||||
if (!(u->cu_mask & U32_ATTR_MARK))
|
||||
return -NLE_INVAL;
|
||||
|
||||
nl_data_free(u->cu_mark);
|
||||
u->cu_mark = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the 32-bit key from the selector
|
||||
*
|
||||
|
|
Loading…
Add table
Reference in a new issue