]> granicus.if.org Git - libnl/commitdiff
add u32 action support
authorCong Wang <xiyou.wangcong@gmail.com>
Fri, 8 Nov 2013 18:47:51 +0000 (10:47 -0800)
committerThomas Graf <tgraf@suug.ch>
Sat, 9 Nov 2013 00:16:14 +0000 (01:16 +0100)
Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com>
Signed-off-by: Thomas Graf <tgraf@suug.ch>
include/netlink-private/types.h
include/netlink/route/cls/u32.h
lib/route/cls/u32.c

index 6d38c1a9cbd5df6a2414e72cd1953f784772068c..99fea27fc145f0b2c75cbc7aec13a36ad32ae24c 100644 (file)
@@ -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;
index 59bed334e4b8bdaaf84fc177eebe90e236e8d029..5d8d1abec26623e7bd7d47fde83e5a5f267d0d6c 100644 (file)
@@ -15,6 +15,7 @@
 #include <netlink/netlink.h>
 #include <netlink/cache.h>
 #include <netlink/route/classifier.h>
+#include <netlink/route/action.h>
 
 #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
 }
index c468ba726824cb4c476a0c3a8ee413244f27d2b7..687690ddda2e735068b43f71df867080dca2325c 100644 (file)
@@ -26,6 +26,7 @@
 #include <netlink-private/route/tc-api.h>
 #include <netlink/route/classifier.h>
 #include <netlink/route/cls/u32.h>
+#include <netlink/route/action.h>
 
 /** @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);
+}
+
 /** @} */
 
 /**