summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdrian Ban <adrian.ban@mantech.ro>2012-05-08 23:14:13 +0200
committerThomas Graf <tgraf@redhat.com>2012-05-08 23:14:13 +0200
commitbeb40e2b4ed22ab11867b8c7e68d3be9da64fed8 (patch)
treec64833ce3c91e863eb81886c970612b9b04f869f
parentf8b4f9271b86c7294c7f87270e74b8c690798dd9 (diff)
downloadlibnl-beb40e2b4ed22ab11867b8c7e68d3be9da64fed8.tar.gz
u32: add support for hashing
-rw-r--r--include/netlink/route/cls/u32.h4
-rw-r--r--lib/route/cls/u32.c85
2 files changed, 89 insertions, 0 deletions
diff --git a/include/netlink/route/cls/u32.h b/include/netlink/route/cls/u32.h
index cf35e26..62c5386 100644
--- a/include/netlink/route/cls/u32.h
+++ b/include/netlink/route/cls/u32.h
@@ -21,6 +21,10 @@ extern "C" {
extern void rtnl_u32_set_handle(struct rtnl_cls *, int, int, int);
extern int rtnl_u32_set_classid(struct rtnl_cls *, uint32_t);
+extern int rtnl_u32_set_divisor(struct rtnl_cls *, uint32_t);
+extern int rtnl_u32_set_link(struct rtnl_cls *, uint32_t);
+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_key(struct rtnl_cls *, uint32_t, uint32_t,
diff --git a/lib/route/cls/u32.c b/lib/route/cls/u32.c
index 2016460..331e714 100644
--- a/lib/route/cls/u32.c
+++ b/lib/route/cls/u32.c
@@ -374,6 +374,91 @@ int rtnl_u32_set_classid(struct rtnl_cls *cls, uint32_t classid)
return 0;
}
+int rtnl_u32_set_divisor(struct rtnl_cls *cls, uint32_t divisor)
+{
+ struct rtnl_u32 *u;
+
+ if (!(u = (struct rtnl_u32 *) rtnl_tc_data(TC_CAST(cls))))
+ return -NLE_NOMEM;
+
+ u->cu_divisor = divisor;
+ u->cu_mask |= U32_ATTR_DIVISOR;
+ return 0;
+}
+
+int rtnl_u32_set_link(struct rtnl_cls *cls, uint32_t link)
+{
+ struct rtnl_u32 *u;
+
+ if (!(u = (struct rtnl_u32 *) rtnl_tc_data(TC_CAST(cls))))
+ return -NLE_NOMEM;
+
+ u->cu_link = link;
+ u->cu_mask |= U32_ATTR_LINK;
+ return 0;
+}
+
+int rtnl_u32_set_hashtable(struct rtnl_cls *cls, uint32_t ht)
+{
+ struct rtnl_u32 *u;
+
+ if (!(u = (struct rtnl_u32 *) rtnl_tc_data(TC_CAST(cls))))
+ return -NLE_NOMEM;
+
+ u->cu_hash = ht;
+ u->cu_mask |= U32_ATTR_HASH;
+ return 0;
+}
+
+int rtnl_u32_set_hashmask(struct rtnl_cls *cls, uint32_t hashmask, uint32_t offset)
+{
+ struct rtnl_u32 *u;
+ struct tc_u32_sel *sel;
+ int err;
+
+ hashmask = htonl(hashmask);
+
+ if (!(u = (struct rtnl_u32 *) rtnl_tc_data(TC_CAST(cls))))
+ return -NLE_NOMEM;
+
+ sel = u32_selector_alloc(u);
+ if (!sel)
+ return -NLE_NOMEM;
+
+ err = nl_data_append(u->cu_selector, NULL, sizeof(struct tc_u32_key));
+ if(err < 0)
+ return err;
+
+ sel = u32_selector(u);
+
+ sel->hmask = hashmask;
+ sel->hoff = offset;
+ return 0;
+}
+
+int rtnl_u32_set_cls_terminal(struct rtnl_cls *cls)
+{
+ struct rtnl_u32 *u;
+ struct tc_u32_sel *sel;
+ int err;
+
+ if (!(u = (struct rtnl_u32 *) rtnl_tc_data(TC_CAST(cls))))
+ return -NLE_NOMEM;
+
+ sel = u32_selector_alloc(u);
+ if (!sel)
+ return -NLE_NOMEM;
+
+ err = nl_data_append(u->cu_selector, NULL, sizeof(struct tc_u32_key));
+ if(err < 0)
+ return err;
+
+ sel = u32_selector(u);
+
+ sel->flags |= TC_U32_TERMINAL;
+ return 0;
+}
+
/** @} */
/**