/* * Function that adds a new filter and attach it to a hash table * and set next hash table link with hash mask * */ static 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_act *act, struct rtnl_act *act2) { struct rtnl_cls *cls; int err; 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(0xffff, 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); rtnl_u32_add_action(cls, act); rtnl_u32_add_action(cls, act2); 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 ingress qdisc and set the default class for unclassified traffic */ static int qdisc_add_ingress(struct nl_sock *sock, struct rtnl_link *rtnlLink) { 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); //printf("Delete current qdisc\n"); rtnl_qdisc_delete(sock, qdisc); //rtnl_qdisc_put(qdisc); rtnl_tc_set_handle(TC_CAST(qdisc), TC_HANDLE(0xffff, 0)); if ((err = rtnl_tc_set_kind(TC_CAST(qdisc), "ingress"))) { printf("Can not allocate ingress\n"); return -1; } /* Submit request to kernel and wait for response */ if ((err = rtnl_qdisc_add(sock, qdisc, NLM_F_CREATE))) { printf("Can not allocate ingress Qdisc\n"); return -1; } /* Return the qdisc object to free memory resources */ rtnl_qdisc_put(qdisc); return 0; }
/* * function that creates a new hash table */ static 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(0xffff, 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; }
uint32_t TcHandle(uint16_t maj, uint16_t min) { return TC_HANDLE(maj, min); }