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; }
void nl_cli_cls_parse_proto(struct rtnl_cls *cls, char *arg) { int proto; if ((proto = nl_str2ether_proto(arg)) < 0) nl_cli_fatal(proto, "Unknown protocol \"%s\".", arg); rtnl_cls_set_protocol(cls, proto); }
Try<Nothing> encode<basic::Classifier>( const Netlink<struct rtnl_cls>& cls, const basic::Classifier& classifier) { rtnl_cls_set_protocol(cls.get(), classifier.protocol()); int error = rtnl_tc_set_kind(TC_CAST(cls.get()), "basic"); if (error != 0) { return Error( "Failed to set the kind of the classifier: " + string(nl_geterror(error))); } return Nothing(); }
/* * 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; }
Try<Nothing> encode<icmp::Classifier>( const Netlink<struct rtnl_cls>& cls, const icmp::Classifier& classifier) { // ICMP packets are one type of IP packets. rtnl_cls_set_protocol(cls.get(), ETH_P_IP); int error = rtnl_tc_set_kind(TC_CAST(cls.get()), "u32"); if (error != 0) { return Error( "Failed to set the kind of the classifier: " + string(nl_geterror(error))); } // To avoid confusion, we only use u32 selectors which are used to // match arbitrary 32-bit content in a packet. // Format of an IP packet at offset 8. The IP protocol field is at // offset 9. ICMP has protocol = 1. // +--------+--------+--------+--------+ // | X | Proto. | X | X | // +--------+--------+--------+--------+ // Offset: 8 9 10 11 uint32_t protocol = 0x00010000; uint32_t mask = 0x00ff0000; // Ignore offset 8, 10, 11. // To match ICMP packets (protocol = 1). error = rtnl_u32_add_key( cls.get(), htonl(protocol), htonl(mask), 8, // Offset from which to start matching. 0); if (error != 0) { return Error( "Failed to add selector for IP protocol: " + string(nl_geterror(error))); } if (classifier.destinationIP.isSome()) { Try<struct in_addr> in = classifier.destinationIP.get().in(); if (in.isError()) { return Error("Destination IP is not an IPv4 address"); } // To match those IP packets that have the given destination IP. error = rtnl_u32_add_key( cls.get(), in.get().s_addr, htonl(0xffffffff), 16, // Offset from which to start matching. 0); if (error != 0) { return Error( "Failed to add selector for destination IP address: " + string(nl_geterror(error))); } } return Nothing(); }