From 6cdc32df831a273007af7d24a3f75cd06e0ae738 Mon Sep 17 00:00:00 2001 From: Cong Wang Date: Fri, 8 Nov 2013 10:47:51 -0800 Subject: add u32 action support Signed-off-by: Cong Wang Signed-off-by: Thomas Graf --- include/netlink-private/types.h | 2 +- include/netlink/route/cls/u32.h | 2 ++ lib/route/cls/u32.c | 36 +++++++++++++++++++++++++++++------- 3 files changed, 32 insertions(+), 8 deletions(-) diff --git a/include/netlink-private/types.h b/include/netlink-private/types.h index 6d38c1a..99fea27 100644 --- a/include/netlink-private/types.h +++ b/include/netlink-private/types.h @@ -522,7 +522,7 @@ struct rtnl_u32 uint32_t cu_link; struct nl_data * cu_pcnt; struct nl_data * cu_selector; - struct nl_data * cu_act; + struct rtnl_act* cu_act; struct nl_data * cu_police; char cu_indev[IFNAMSIZ]; int cu_mask; diff --git a/include/netlink/route/cls/u32.h b/include/netlink/route/cls/u32.h index 59bed33..5d8d1ab 100644 --- a/include/netlink/route/cls/u32.h +++ b/include/netlink/route/cls/u32.h @@ -15,6 +15,7 @@ #include #include #include +#include #ifdef __cplusplus extern "C" { @@ -41,6 +42,7 @@ extern int rtnl_u32_add_key_in_addr(struct rtnl_cls *, struct in_addr *, uint8_t, int, int); extern int rtnl_u32_add_key_in6_addr(struct rtnl_cls *, struct in6_addr *, uint8_t, int, int); +extern int rtnl_u32_add_action(struct rtnl_cls *, struct rtnl_act *); #ifdef __cplusplus } diff --git a/lib/route/cls/u32.c b/lib/route/cls/u32.c index c468ba7..687690d 100644 --- a/lib/route/cls/u32.c +++ b/lib/route/cls/u32.c @@ -26,6 +26,7 @@ #include #include #include +#include /** @cond SKIP */ #define U32_ATTR_DIVISOR 0x001 @@ -101,10 +102,10 @@ static int u32_msg_parser(struct rtnl_tc *tc, void *data) } if (tb[TCA_U32_ACT]) { - u->cu_act = nl_data_alloc_attr(tb[TCA_U32_ACT]); - if (!u->cu_act) - goto errout_nomem; u->cu_mask |= U32_ATTR_ACTION; + err = rtnl_act_parse(&u->cu_act, tb[TCA_U32_ACT]); + if (err) + return err; } if (tb[TCA_U32_POLICE]) { @@ -154,8 +155,9 @@ static void u32_free_data(struct rtnl_tc *tc, void *data) { struct rtnl_u32 *u = data; + if (u->cu_act) + rtnl_act_put_all(&u->cu_act); nl_data_free(u->cu_selector); - nl_data_free(u->cu_act); nl_data_free(u->cu_police); nl_data_free(u->cu_pcnt); } @@ -168,8 +170,9 @@ static int u32_clone(void *_dst, void *_src) !(dst->cu_selector = nl_data_clone(src->cu_selector))) return -NLE_NOMEM; - if (src->cu_act && !(dst->cu_act = nl_data_clone(src->cu_act))) + if (src->cu_act && !(dst->cu_act = rtnl_act_alloc())) return -NLE_NOMEM; + memcpy(dst->cu_act, src->cu_act, sizeof(struct rtnl_act)); if (src->cu_police && !(dst->cu_police = nl_data_clone(src->cu_police))) return -NLE_NOMEM; @@ -333,8 +336,13 @@ 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_ACTION) - NLA_PUT_DATA(msg, TCA_U32_ACT, u->cu_act); + if (u->cu_mask & U32_ATTR_ACTION) { + int err; + + err = rtnl_act_fill(msg, TCA_U32_ACT, u->cu_act); + if (err) + return err; + } if (u->cu_mask & U32_ATTR_POLICE) NLA_PUT_DATA(msg, TCA_U32_POLICE, u->cu_police); @@ -459,6 +467,20 @@ int rtnl_u32_set_cls_terminal(struct rtnl_cls *cls) return 0; } +int rtnl_u32_add_action(struct rtnl_cls *cls, struct rtnl_act *act) +{ + struct rtnl_u32 *u; + + if (!act) + return 0; + + if (!(u = rtnl_tc_data(TC_CAST(cls)))) + return -NLE_NOMEM; + + u->cu_mask |= U32_ATTR_ACTION; + return rtnl_act_append(&u->cu_act, act); +} + /** @} */ /** -- cgit v0.12