summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorAdrian Ban <adrian.ban@mantech.ro>2012-05-08 23:17:53 +0200
committerThomas Graf <tgraf@redhat.com>2012-05-08 23:17:53 +0200
commit7b503a12a039aeb129fb75804824f6b365adb54b (patch)
treeaadf5adb0a8cb84c7d73d05ad112035d9a092eef /tests
parentbeb40e2b4ed22ab11867b8c7e68d3be9da64fed8 (diff)
downloadlibnl-7b503a12a039aeb129fb75804824f6b365adb54b.tar.gz
u32: example/test code for u32 hashing with HTB
Diffstat (limited to 'tests')
-rw-r--r--tests/.gitignore4
-rw-r--r--tests/Makefile.am4
-rw-r--r--tests/test-complex-HTB-with-hash-filters.c753
3 files changed, 760 insertions, 1 deletions
diff --git a/tests/.gitignore b/tests/.gitignore
index 19184ee..b386c45 100644
--- a/tests/.gitignore
+++ b/tests/.gitignore
@@ -1,4 +1,8 @@
test-cache-mngr
+test-complex-HTB-with-hash-filters
+test-create-bond
+test-create-vlan
+test-delete-link
test-genl
test-nf-cache-mngr
test-socket-creation
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 4193818..1272f98 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -16,7 +16,8 @@ check_PROGRAMS = \
test-delete-link \
test-genl \
test-nf-cache-mngr \
- test-socket-creation
+ test-socket-creation \
+ test-complex-HTB-with-hash-filters
# Eventually add these to TESTS once converted to be real
# test programs
@@ -29,3 +30,4 @@ test_delete_link_SOURCES = test-delete-link.c
test_genl_SOURCES = test-genl.c
test_nf_cache_mngr_SOURCES = test-nf-cache-mngr.c
test_socket_creation_SOURCES = test-socket-creation.c
+test_complex_HTB_with_hash_filters_SOURCES = test-complex-HTB-with-hash-filters.c
diff --git a/tests/test-complex-HTB-with-hash-filters.c b/tests/test-complex-HTB-with-hash-filters.c
new file mode 100644
index 0000000..585a549
--- /dev/null
+++ b/tests/test-complex-HTB-with-hash-filters.c
@@ -0,0 +1,753 @@
+/*
+ * test/test-complex-HTB-with-hash-filters.c Add HTB qdisc, HTB classes and creates some hash filters
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation version 2.1
+ * of the License.
+ *
+ * Copyright (c) 2011 Adrian Ban <adrian.ban@mantech.ro>
+ */
+
+#include <netlink/route/link.h>
+#include <netlink/route/tc.h>
+#include <netlink/route/qdisc.h>
+#include <netlink/route/classifier.h>
+#include <linux/if_ether.h>
+
+#include <netlink/attr.h>
+//#include "include/rtnl_u32.h"
+
+#include <stdio.h>
+#include <string.h>
+//#include "include/rtnl_u32_addon.h"
+
+#define TC_HANDLE(maj, min) (TC_H_MAJ((maj) << 16) | TC_H_MIN(min))
+
+/* some functions are copied from iproute-tc tool */
+int get_u32(__u32 *val, const char *arg, int base)
+{
+ unsigned long res;
+ char *ptr;
+
+ if (!arg || !*arg)
+ return -1;
+ res = strtoul(arg, &ptr, base);
+ if (!ptr || ptr == arg || *ptr || res > 0xFFFFFFFFUL)
+ return -1;
+ *val = res;
+ return 0;
+}
+
+int get_u32_handle(__u32 *handle, const char *str)
+{
+ __u32 htid=0, hash=0, nodeid=0;
+ char *tmp = strchr(str, ':');
+
+ if (tmp == NULL) {
+ if (memcmp("0x", str, 2) == 0)
+ return get_u32(handle, str, 16);
+ return -1;
+ }
+ htid = strtoul(str, &tmp, 16);
+ if (tmp == str && *str != ':' && *str != 0)
+ return -1;
+ if (htid>=0x1000)
+ return -1;
+ if (*tmp) {
+ str = tmp+1;
+ hash = strtoul(str, &tmp, 16);
+ if (tmp == str && *str != ':' && *str != 0)
+ return -1;
+ if (hash>=0x100)
+ return -1;
+ if (*tmp) {
+ str = tmp+1;
+ nodeid = strtoul(str, &tmp, 16);
+ if (tmp == str && *str != 0)
+ return -1;
+ if (nodeid>=0x1000)
+ return -1;
+ }
+ }
+ *handle = (htid<<20)|(hash<<12)|nodeid;
+ return 0;
+}
+
+uint32_t get_u32_parse_handle(const char *cHandle)
+{
+ uint32_t handle=0;
+
+ if(get_u32_handle(&handle, cHandle)) {
+ printf ("Illegal \"ht\"\n");
+ return -1;
+ }
+
+ if (handle && TC_U32_NODE(handle)) {
+ printf("\"link\" must be a hash table.\n");
+ return -1;
+ }
+ return handle;
+}
+
+int get_tc_classid(__u32 *h, const char *str)
+{
+ __u32 maj, min;
+ char *p;
+
+ maj = TC_H_ROOT;
+ if (strcmp(str, "root") == 0)
+ goto ok;
+ maj = TC_H_UNSPEC;
+ if (strcmp(str, "none") == 0)
+ goto ok;
+ maj = strtoul(str, &p, 16);
+ if (p == str) {
+ maj = 0;
+ if (*p != ':')
+ return -1;
+ }
+ if (*p == ':') {
+ if (maj >= (1<<16))
+ return -1;
+ maj <<= 16;
+ str = p+1;
+ min = strtoul(str, &p, 16);
+ if (*p != 0)
+ return -1;
+ if (min >= (1<<16))
+ return -1;
+ maj |= min;
+ } else if (*p != 0)
+ return -1;
+
+ok:
+ *h = maj;
+ return 0;
+}
+
+/*
+ * Function that adds a new filter and attach it to a hash table
+ *
+ */
+int u32_add_filter_on_ht(struct nl_sock *sock, struct rtnl_link *rtnlLink, uint32_t prio,
+ uint32_t keyval, uint32_t keymask, int keyoff, int keyoffmask,
+ uint32_t htid, uint32_t classid
+)
+{
+ struct rtnl_cls *cls;
+ int err;
+
+ //printf("Key Val : 0x%x\n", keyval);
+ //printf("Key Mask : 0x%x\n", keymask);
+
+ cls=rtnl_cls_alloc();
+ if (!(cls)) {
+ printf("Can not allocate classifier\n");
+ nl_socket_free(sock);
+ exit(1);
+ }
+
+ rtnl_tc_set_link(TC_CAST(cls), rtnlLink);
+
+ if (err = rtnl_tc_set_kind(TC_CAST(cls), "u32")) {
+ printf("Can not set classifier as u32\n");
+ return 1;
+ }
+
+ rtnl_cls_set_prio(cls, prio);
+ rtnl_cls_set_protocol(cls, ETH_P_IP);
+
+ rtnl_tc_set_parent(TC_CAST(cls), TC_HANDLE(1, 0));
+
+ rtnl_u32_set_hashtable(cls, htid);
+
+ rtnl_u32_add_key_uint32(cls, keyval, keymask, keyoff, keyoffmask); /* 10.0.0.0/8 */
+
+ rtnl_u32_set_classid(cls, classid);
+
+ rtnl_u32_set_cls_terminal(cls);
+
+ if (err = rtnl_cls_add(sock, cls, NLM_F_CREATE)) {
+ printf("Can not add classifier: %s\n", nl_geterror(err));
+ return -1;
+ }
+ rtnl_cls_put(cls);
+ return 0;
+
+}
+
+/*
+ * Function that adds a new filter and attach it to a hash table
+ * and set next hash table link with hash mask
+ *
+ */
+int u32_add_filter_on_ht_with_hashmask(struct nl_sock *sock, struct rtnl_link *rtnlLink, uint32_t prio,
+ uint32_t keyval, uint32_t keymask, int keyoff, int keyoffmask,
+ uint32_t htid, uint32_t htlink, uint32_t hmask, uint32_t hoffset
+)
+{
+ struct rtnl_cls *cls;
+ int err;
+
+ //printf("Key Val : 0x%x\n", keyval);
+ //printf("Key Mask : 0x%x\n", keymask);
+
+ cls=rtnl_cls_alloc();
+ if (!(cls)) {
+ printf("Can not allocate classifier\n");
+ nl_socket_free(sock);
+ exit(1);
+ }
+
+ rtnl_tc_set_link(TC_CAST(cls), rtnlLink);
+
+ if (err = rtnl_tc_set_kind(TC_CAST(cls), "u32")) {
+ printf("Can not set classifier as u32\n");
+ return 1;
+ }
+
+ rtnl_cls_set_prio(cls, prio);
+ rtnl_cls_set_protocol(cls, ETH_P_IP);
+
+ rtnl_tc_set_parent(TC_CAST(cls), TC_HANDLE(1, 0));
+
+ if (htid)
+ rtnl_u32_set_hashtable(cls, htid);
+
+ rtnl_u32_add_key_uint32(cls, keyval, keymask, keyoff, keyoffmask);
+
+ rtnl_u32_set_hashmask(cls, hmask, hoffset);
+
+ rtnl_u32_set_link(cls, htlink);
+
+
+ if (err = rtnl_cls_add(sock, cls, NLM_F_CREATE)) {
+ printf("Can not add classifier: %s\n", nl_geterror(err));
+ return -1;
+ }
+ rtnl_cls_put(cls);
+ return 0;
+}
+
+/*
+ * function that creates a new hash table
+ */
+int u32_add_ht(struct nl_sock *sock, struct rtnl_link *rtnlLink, uint32_t prio, uint32_t htid, uint32_t divisor)
+{
+
+ int err;
+ struct rtnl_cls *cls;
+
+ cls=rtnl_cls_alloc();
+ if (!(cls)) {
+ printf("Can not allocate classifier\n");
+ nl_socket_free(sock);
+ exit(1);
+ }
+
+ rtnl_tc_set_link(TC_CAST(cls), rtnlLink);
+
+ if (err = rtnl_tc_set_kind(TC_CAST(cls), "u32")) {
+ printf("Can not set classifier as u32\n");
+ return 1;
+ }
+
+ rtnl_cls_set_prio(cls, prio);
+ rtnl_cls_set_protocol(cls, ETH_P_IP);
+ rtnl_tc_set_parent(TC_CAST(cls), TC_HANDLE(1, 0));
+
+ rtnl_u32_set_handle(cls, htid, 0x0, 0x0);
+ //printf("htid: 0x%X\n", htid);
+ rtnl_u32_set_divisor(cls, divisor);
+
+ if (err = rtnl_cls_add(sock, cls, NLM_F_CREATE)) {
+ printf("Can not add classifier: %s\n", nl_geterror(err));
+ return -1;
+ }
+ rtnl_cls_put(cls);
+ return 0;
+}
+
+/*
+ * function that adds a new HTB qdisc and set the default class for unclassified traffic
+ */
+int qdisc_add_HTB(struct nl_sock *sock, struct rtnl_link *rtnlLink, uint32_t defaultClass)
+{
+
+ struct rtnl_qdisc *qdisc;
+ int err;
+
+ /* Allocation of a qdisc object */
+ if (!(qdisc = rtnl_qdisc_alloc())) {
+ printf("Can not allocate Qdisc\n");
+ return -1;
+ }
+
+ //rtnl_tc_set_ifindex(TC_CAST(qdisc), master_index);
+ rtnl_tc_set_link(TC_CAST(qdisc), rtnlLink);
+ rtnl_tc_set_parent(TC_CAST(qdisc), TC_H_ROOT);
+
+ //delete the qdisc
+ //printf("Delete current qdisc\n");
+ rtnl_qdisc_delete(sock, qdisc);
+ //rtnl_qdisc_put(qdisc);
+
+ //add a HTB qdisc
+ //printf("Add a new HTB qdisc\n");
+ rtnl_tc_set_handle(TC_CAST(qdisc), TC_HANDLE(1,0));
+
+ if (err = rtnl_tc_set_kind(TC_CAST(qdisc), "htb") ){
+ printf("Can not allocate HTB\n");
+ return -1;
+ }
+
+ /* Set default class for unclassified traffic */
+ //printf("Set default class for unclassified traffic\n");
+ rtnl_htb_set_defcls(qdisc, TC_HANDLE(1, defaultClass));
+ rtnl_htb_set_rate2quantum(qdisc, 1);
+
+ /* Submit request to kernel and wait for response */
+ if (err = rtnl_qdisc_add(sock, qdisc, NLM_F_CREATE)) {
+ printf("Can not allocate HTB Qdisc\n");
+ return -1;
+ }
+
+ /* Return the qdisc object to free memory resources */
+ rtnl_qdisc_put(qdisc);
+
+}
+
+/*
+ * function that adds a new HTB class and set its parameters
+ */
+int class_add_HTB(struct nl_sock *sock, struct rtnl_link *rtnlLink,
+ uint32_t parentMaj, uint32_t parentMin,
+ uint32_t childMaj, uint32_t childMin,
+ uint64_t rate, uint64_t ceil,
+ uint32_t burst, uint32_t cburst,
+ uint32_t prio
+)
+{
+ int err;
+ struct rtnl_class *class;
+
+ //create a HTB class
+ class = (struct rtnl_class *)rtnl_class_alloc();
+ //class = rtnl_class_alloc();
+ if (!class) {
+ printf("Can not allocate class object\n");
+ return 1;
+ }
+ //
+ rtnl_tc_set_link(TC_CAST(class), rtnlLink);
+ //add a HTB qdisc
+ //printf("Add a new HTB class with 0x%X:0x%X on parent 0x%X:0x%X\n", childMaj, childMin, parentMaj, parentMin);
+ rtnl_tc_set_parent(TC_CAST(class), TC_HANDLE(parentMaj, parentMin));
+ rtnl_tc_set_handle(TC_CAST(class), TC_HANDLE(childMaj, childMin));
+
+ if (err = rtnl_tc_set_kind(TC_CAST(class), "htb") ){
+ printf("Can not set HTB to class\n");
+ return 1;
+ }
+
+ //printf("set HTB class prio to %u\n", prio);
+ rtnl_htb_set_prio(class, prio);
+
+ if (rate) {
+ //rate=rate/8;
+ rtnl_htb_set_rate(class, rate);
+ }
+ if (ceil) {
+ //ceil=ceil/8;
+ rtnl_htb_set_ceil(class, ceil);
+ }
+
+ if (burst) {
+ //printf ("Class HTB: set rate burst: %u\n", burst);
+ rtnl_htb_set_rbuffer(class, burst);
+ }
+ if (cburst) {
+ //printf ("Class HTB: set rate cburst: %u\n", cburst);
+ rtnl_htb_set_cbuffer(class, cburst);
+ }
+ /* Submit request to kernel and wait for response */
+ if (err = rtnl_class_add(sock, class, NLM_F_CREATE)) {
+ printf("Can not allocate HTB Qdisc\n");
+ return 1;
+ }
+ rtnl_class_put(class);
+
+}
+
+/*
+ * function that adds a HTB root class and set its parameters
+ */
+int class_add_HTB_root(struct nl_sock *sock, struct rtnl_link *rtnlLink,
+ uint64_t rate, uint64_t ceil,
+ uint32_t burst, uint32_t cburst
+)
+{
+ int err;
+ struct rtnl_class *class;
+
+ //create a HTB class
+ class = (struct rtnl_class *)rtnl_class_alloc();
+ //class = rtnl_class_alloc();
+ if (!class) {
+ printf("Can not allocate class object\n");
+ return 1;
+ }
+ //
+ rtnl_tc_set_link(TC_CAST(class), rtnlLink);
+ rtnl_tc_set_parent(TC_CAST(class), TC_H_ROOT);
+ //add a HTB class
+ //printf("Add a new HTB ROOT class\n");
+ rtnl_tc_set_handle(TC_CAST(class), 1);
+
+ if (err = rtnl_tc_set_kind(TC_CAST(class), "htb") ){
+ printf("Can not set HTB to class\n");
+ return 1;
+ }
+
+ if (rate) {
+ //rate=rate/8;
+ rtnl_htb_set_rate(class, rate);
+ }
+ if (ceil) {
+ //ceil=ceil/8;
+ rtnl_htb_set_ceil(class, ceil);
+ }
+
+ if (burst) {
+ rtnl_htb_set_rbuffer(class, burst);
+ }
+ if (cburst) {
+ rtnl_htb_set_cbuffer(class, cburst);
+ }
+
+ /* Submit request to kernel and wait for response */
+ if (err = rtnl_class_add(sock, class, NLM_F_CREATE)) {
+ printf("Can not allocate HTB Qdisc\n");
+ return 1;
+ }
+ rtnl_class_put(class);
+
+}
+
+/*
+ * function that adds a new SFQ qdisc as a leaf for a HTB class
+ */
+int qdisc_add_SFQ_leaf(struct nl_sock *sock, struct rtnl_link *rtnlLink,
+ uint32_t parentMaj, uint32_t parentMin,
+ int quantum, int limit, int perturb
+)
+{
+ int err;
+ struct rtnl_qdisc *qdisc;
+
+ if (!(qdisc = rtnl_qdisc_alloc())) {
+ printf("Can not allocate qdisc object\n");
+ return 1;
+ }
+ rtnl_tc_set_link(TC_CAST(qdisc), rtnlLink);
+ rtnl_tc_set_parent(TC_CAST(qdisc), TC_HANDLE(parentMaj, parentMin));
+
+ rtnl_tc_set_handle(TC_CAST(qdisc), TC_HANDLE(parentMin,0));
+
+ if (err = rtnl_tc_set_kind(TC_CAST(qdisc), "sfq") ){
+ printf("Can not set SQF class\n");
+ return 1;
+ }
+
+ if(quantum) {
+ rtnl_sfq_set_quantum(qdisc, quantum);
+ } else {
+ rtnl_sfq_set_quantum(qdisc, 16000); // tc default value
+ }
+ if(limit) {
+ rtnl_sfq_set_limit(qdisc, limit); // default is 127
+ }
+ if(perturb) {
+ rtnl_sfq_set_perturb(qdisc, perturb); // default never perturb the hash
+ }
+
+ /* Submit request to kernel and wait for response */
+ if (err = rtnl_qdisc_add(sock, qdisc, NLM_F_CREATE)) {
+ printf("Can not allocate SFQ qdisc\n");
+ return -1;
+ }
+
+ /* Return the qdisc object to free memory resources */
+ rtnl_qdisc_put(qdisc);
+}
+
+
+
+
+int main() {
+
+ struct nl_sock *sock;
+ struct rtnl_link *link;
+
+ struct rtnl_qdisc *qdisc;
+ struct rtnl_class *class;
+ struct rtnl_cls *cls;
+
+ uint32_t ht, htlink, htid, handle, divisor, hash, nodeid, hashmask, direction, classid;
+ struct rtnl_u32 *f_u32;
+ char chashlink[16]="";
+
+ uint64_t drops, qlen;
+
+ int master_index;
+ int err;
+
+ uint64_t rate=0, ceil=0;
+
+ struct nl_cache *link_cache;
+
+ if (!(sock = nl_socket_alloc())) {
+ printf("Unable to allocate netlink socket\n");
+ exit(1);
+ }
+
+ if ((err = nl_connect(sock, NETLINK_ROUTE)) < 0 ) {
+ printf("Nu s-a putut conecta la NETLINK!\n");
+ nl_socket_free(sock);
+ exit(1);
+ }
+
+
+ if ((err = rtnl_link_alloc_cache(sock, AF_UNSPEC, &link_cache)) < 0) {
+ printf("Unable to allocate link cache: %s\n",
+ nl_geterror(err));
+ nl_socket_free(sock);
+ exit(1);
+ }
+
+ /* lookup interface index of eth0 */
+ if (!(link = rtnl_link_get_by_name(link_cache, "eth0"))) {
+ /* error */
+ printf("Interface not found\n");
+ nl_socket_free(sock);
+ exit(1);
+ }
+
+ err=qdisc_add_HTB(sock, link, 0xffff);
+ //drops = rtnl_tc_get_stat(TC_CAST(qdisc), RTNL_TC_DROPS);
+
+ //printf("Add ROOT HTB class\n");
+ err=class_add_HTB_root(sock, link, 12500000, 12500000, 25000, 25000);
+ err=class_add_HTB(sock, link, 1, 0, 1, 0xffff, 1250000, 12500000, 25000, 25000, 5);
+ err=qdisc_add_SFQ_leaf(sock, link, 1, 0xffff, 16000, 0, 10);
+ err=class_add_HTB(sock, link, 1, 1, 1, 0x5, 2000000, 2000000, 25000, 25000, 5);
+ err=qdisc_add_SFQ_leaf(sock, link, 1, 0x5, 16000, 0, 10);
+ err=class_add_HTB(sock, link, 1, 1, 1, 0x6, 1000000, 1000000, 25000, 25000, 5);
+ err=qdisc_add_SFQ_leaf(sock, link, 1, 0x6, 16000, 0, 10);
+ //err=class_add_HTB(sock, link, 1, 0, 1, 0x7, 1024000, 100000000, 5);
+ //err=class_add_HTB(sock, link, 1, 0, 1, 0x8, 2048000, 100000000, 5);
+ //err=class_add_HTB(sock, link, 1, 0, 1, 0x9, 4096000, 100000000, 5);
+ //err=class_add_HTB(sock, link, 1, 0, 1, 0xa, 8192000, 100000000, 5);
+
+ //printf("Add main hash table\n");
+
+ /* create u32 first hash filter table
+ *
+ */
+ /* formula calcul handle:
+ * uint32_t handle = (htid << 20) | (hash << 12) | nodeid;
+ */
+
+ /*
+ * Upper limit of number of hash tables: 4096 (0xFFF)
+ * Number of hashes in a table: 256 values (0xFF)
+ *
+ */
+
+ /* using 256 values for hash table
+ * each entry in hash table match a byte from IP address specified later by a hash key
+ */
+
+ uint32_t i;
+ for (i = 1; i <= 0xf; i++)
+ u32_add_ht(sock, link, 1, i, 256);
+
+ /*
+ * attach a u32 filter to the first hash
+ * that redirects all traffic and make a hash key
+ * from the fist byte of the IP address
+ *
+ */
+
+ divisor=0x0; // unused here
+ handle = 0x0; // unused here
+ hash = 0x0; // unused here
+ htid = 0x0; // unused here
+ nodeid = 0x0; // unused here
+ uint32_t hashlink;
+
+ direction = 16;
+
+ /*
+ * which hash table will use
+ * in our case is hash table no 1 defined previous
+ *
+ * There are 2 posibilities to set the the hash table:
+ * 1. Using function get_u32_handle and sent a string in
+ * format 10: where 10 is number of the hash table
+ * 2. Create your own value in format: 0xa00000
+ *
+ */
+ strcpy(chashlink, "1:");
+ //printf("Hash Link: %s\n", chashlink);
+ //chashlink=malloc(sizeof(char) *
+ htlink = 0x0; // is used by get_u32_handle to return the correct value of hash table (link)
+
+ if(get_u32_handle(&htlink, chashlink)) {
+ printf ("Illegal \"link\"");
+ nl_socket_free(sock);
+ exit(1);
+ }
+ //printf ("hash link : 0x%X\n", htlink);
+ //printf ("hash link test : %u\n", (htlink && TC_U32_NODE(htlink)));
+
+ if (htlink && TC_U32_NODE(htlink)) {
+ printf("\"link\" must be a hash table.\n");
+ nl_socket_free(sock);
+ exit(1);
+ }
+ /* the hash mask will hit the hash table (link) no 1: in our case
+ */
+
+ /* set the hash key mask */
+ //hashmask = 0xFF000000UL; // the mask that is used to match the hash in specific table, in our case for example 1:a with mean the first byte which is 10 in hash table 1
+
+ /* Here we add a hash filter which match the first byte (see the hashmask value)
+ * of the source IP (offset 12 in the packet header)
+ * You can use also offset 16 to match the destination IP
+ */
+
+ /*
+ * Also we need a filter to match our rule
+ * This mean that we will put a 0.0.0.0/0 filter in our first rule
+ * that match the offset 12 (source IP)
+ * Also you can put offset 16 to match the destination IP
+ */
+
+ u32_add_filter_on_ht_with_hashmask(sock, link, 1,
+ 0x0, 0x0, direction, 0,
+ 0, htlink, 0xff000000, direction);
+
+ /*
+ * For each first byte that we need to match we will create a new hash table
+ * For example: you have those clases: 10.0.0.0/24 and 172.16.0.0/23
+ * For byte 10 and byte 172 will create a separate hash table that will match the second
+ * byte from each class.
+ *
+ */
+
+
+ // Create a new hash table with prio 1, id 2 and 256 entries
+// u32_CreateNewHashTable(sock, link, 1, 2, 256);
+ // Create a new hash table with prio 1, id 3 and 256 entries
+// u32_CreateNewHashTable(sock, link, 1, 3, 256);
+// u32_CreateNewHashTable(sock, link, 1, 4, 256);
+// u32_CreateNewHashTable(sock, link, 1, 5, 256);
+
+ /*
+ * Now we will create other filter under (ATENTION) our first hash table (link) 1:
+ * Previous rule redirects the trafic according the hash mask to hash table (link) no 1:
+ * Here we will match the hash tables from 1:0 to 1:ff. Under each hash table we will attach
+ * other rules that matches next byte from IP source/destination IP and we will repeat the
+ * previous steps.
+ *
+ */
+
+
+ // /8 check
+
+ // 10.0.0.0/8
+ ht=get_u32_parse_handle("1:a:");
+ htid = (ht&0xFFFFF000);
+ htlink=get_u32_parse_handle("2:");
+
+ u32_add_filter_on_ht_with_hashmask(sock, link, 1,
+ 0x0a000000, 0xff000000, direction, 0,
+ htid, htlink, 0x00ff0000, direction);
+
+ // 172.0.0.0/8
+ ht=get_u32_parse_handle("1:ac:");
+ htid = (ht&0xFFFFF000);
+ htlink=get_u32_parse_handle("3:");
+
+ u32_add_filter_on_ht_with_hashmask(sock, link, 1,
+ 0xac000000, 0xff000000, direction, 0,
+ htid, htlink, 0x00ff0000, direction);
+
+
+ // /16 check
+ // 10.0.0.0/16
+ ht=get_u32_parse_handle("2:0:");
+ htid = (ht&0xFFFFF000);
+ htlink=get_u32_parse_handle("4:");
+
+ u32_add_filter_on_ht_with_hashmask(sock, link, 1,
+ 0x0a000000, 0xffff0000, direction, 0,
+ htid, htlink, 0x0000ff00, direction);
+
+ // 172.17.0.0/16
+ ht=get_u32_parse_handle("3:11:");
+ htid = (ht&0xFFFFF000);
+ htlink=get_u32_parse_handle("5:");
+
+ u32_add_filter_on_ht_with_hashmask(sock, link, 1,
+ 0xac110000, 0xffff0000, direction, 0,
+ htid, htlink, 0x0000ff00, direction);
+
+ // /24 check
+ // 10.0.9.0/24
+ ht=get_u32_parse_handle("4:9:");
+ htid = (ht&0xFFFFF000);
+ htlink=get_u32_parse_handle("6:");
+
+ u32_add_filter_on_ht_with_hashmask(sock, link, 1,
+ 0x0a000900, 0xffffff00, direction, 0,
+ htid, htlink, 0x000000ff, direction);
+
+ // 172.17.2.0/16
+ ht=get_u32_parse_handle("5:2:");
+ htid = (ht&0xFFFFF000);
+ htlink=get_u32_parse_handle("7:");
+
+ u32_add_filter_on_ht_with_hashmask(sock, link, 1,
+ 0xac110200, 0xffffff00, direction, 0,
+ htid, htlink, 0x000000ff, direction);
+
+
+ // final filters
+ // 10.0.9.20
+ ht=get_u32_parse_handle("6:14:");
+ htid = (ht&0xFFFFF000);
+
+ err = get_tc_classid(&classid, "1:5");
+
+ u32_add_filter_on_ht(sock, link, 1,
+ 0x0a000914, 0xffffffff, direction, 0,
+ htid, classid);
+
+ // 172.17.2.120
+ ht=get_u32_parse_handle("7:78:");
+ htid = (ht&0xFFFFF000);
+
+ err = get_tc_classid(&classid, "1:6");
+
+ u32_add_filter_on_ht(sock, link, 1,
+ 0xac110278, 0xffffffff, direction, 0,
+ htid, classid);
+
+
+
+ nl_socket_free(sock);
+ return 0;
+}