diff -Naur libnl-3.2.3-orig/include/netlink/route/cls/u32.h libnl-3.2.3-u32-addon/include/netlink/route/cls/u32.h --- libnl-3.2.3-orig/include/netlink/route/cls/u32.h 2011-08-16 17:16:01.000000000 +0300 +++ libnl-3.2.3-u32-addon/include/netlink/route/cls/u32.h 2011-11-25 00:30:50.000000000 +0200 @@ -21,6 +21,10 @@ 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 -Naur libnl-3.2.3-orig/lib/route/cls/u32.c libnl-3.2.3-u32-addon/lib/route/cls/u32.c --- libnl-3.2.3-orig/lib/route/cls/u32.c 2011-08-16 17:16:15.000000000 +0300 +++ libnl-3.2.3-u32-addon/lib/route/cls/u32.c 2011-11-24 23:48:34.000000000 +0200 @@ -374,6 +374,91 @@ 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; +} + /** @} */ /**