static int cls_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who, struct nlmsghdr *nlh, struct nl_parser_param *pp) { struct rtnl_cls_ops *cops; struct rtnl_cls *cls; int err; cls = rtnl_cls_alloc(); if (!cls) { err = -NLE_NOMEM; goto errout; } cls->ce_msgtype = nlh->nlmsg_type; err = tca_msg_parser(nlh, (struct rtnl_tca *) cls); if (err < 0) goto errout_free; cls->c_prio = TC_H_MAJ(cls->c_info) >> 16; cls->c_protocol = ntohs(TC_H_MIN(cls->c_info)); cops = rtnl_cls_lookup_ops(cls); if (cops && cops->co_msg_parser && (err = cops->co_msg_parser(cls)) < 0) goto errout_free; err = pp->pp_cb((struct nl_object *) cls, pp); errout_free: rtnl_cls_put(cls); errout: return err; }
TError TNlCgFilter::Remove(const TNlLink &link) { TError error = TError::Success(); struct rtnl_cls *cls; int ret; cls = rtnl_cls_alloc(); if (!cls) return TError(EError::Unknown, std::string("Unable to allocate filter object")); rtnl_tc_set_ifindex(TC_CAST(cls), link.GetIndex()); ret = rtnl_tc_set_kind(TC_CAST(cls), FilterType); if (ret < 0) { error = TError(EError::Unknown, std::string("Unable to set filter type: ") + nl_geterror(ret)); goto free_cls; } rtnl_cls_set_prio(cls, FilterPrio); rtnl_cls_set_protocol(cls, 0); rtnl_tc_set_parent(TC_CAST(cls), Parent); link.Dump("remove", cls); ret = rtnl_cls_delete(link.GetSock(), cls, 0); if (ret < 0) error = TError(EError::Unknown, std::string("Unable to remove filter: ") + nl_geterror(ret)); free_cls: rtnl_cls_put(cls); return error; }
static int cls_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who, struct nlmsghdr *nlh, struct nl_parser_param *pp) { struct rtnl_cls *cls; int err; if (!(cls = rtnl_cls_alloc())) return -NLE_NOMEM; if ((err = rtnl_tc_msg_parse(nlh, TC_CAST(cls))) < 0) goto errout; cls->c_prio = TC_H_MAJ(cls->c_info) >> 16; if (cls->c_prio) cls->ce_mask |= CLS_ATTR_PRIO; cls->c_protocol = ntohs(TC_H_MIN(cls->c_info)); if (cls->c_protocol) cls->ce_mask |= CLS_ATTR_PROTOCOL; err = pp->pp_cb(OBJ_CAST(cls), pp); errout: rtnl_cls_put(cls); return err; }
struct rtnl_cls *nl_cli_cls_alloc(void) { struct rtnl_cls *cls; if (!(cls = rtnl_cls_alloc())) nl_cli_fatal(ENOMEM, "Unable to allocate classifier object"); return cls; }
/** * Call a callback for each filter attached to the qdisc * @arg qdisc the parent qdisc * @arg cache a filter cache including at least all the filters * attached to the specified qdisc * @arg cb callback function * @arg arg argument to be passed to callback function */ void rtnl_qdisc_foreach_cls(struct rtnl_qdisc *qdisc, struct nl_cache *cache, void (*cb)(struct nl_object *, void *), void *arg) { struct rtnl_cls *filter; filter = rtnl_cls_alloc(); if (!filter) return; rtnl_cls_set_ifindex(filter, qdisc->q_ifindex); rtnl_cls_set_parent(filter, qdisc->q_parent); nl_cache_foreach_filter(cache, (struct nl_object *) filter, cb, arg); rtnl_cls_put(filter); }
/* * 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 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; }