/** * \brief Pfring bypass callback function * * \param p a Packet to use information from to trigger bypass * \return 1 if bypass is successful, 0 if not */ static int PfringBypassCallback(Packet *p) { hw_filtering_rule r; /* Only bypass TCP and UDP */ if (!(PKT_IS_TCP(p) || PKT_IS_UDP(p))) { return 0; } /* Bypassing tunneled packets is currently not supported */ if (IS_TUNNEL_PKT(p)) { return 0; } r.rule_family_type = generic_flow_id_rule; r.rule_family.flow_id_rule.action = flow_drop_rule; r.rule_family.flow_id_rule.thread = 0; r.rule_family.flow_id_rule.flow_id = p->pfring_v.flow_id; SCLogDebug("Bypass set for flow ID = %u", p->pfring_v.flow_id); if (pfring_add_hw_rule(p->pfring_v.ptv->pd, &r) < 0) { return 0; } return 1; }
int setup_steering(pfring* thering, const char* addr, int queue) { int rc; static int rule_id = 0; // @HACK! hw_filtering_rule rule; intel_82599_perfect_filter_hw_rule *perfect_rule; if (thering == 0 || addr == 0) { errno = EINVAL; return -1; } printf("### Perfect Rule Example ###\n"); rc = pfring_set_filtering_mode(thering, hardware_only); printf("pfring_set_filtering_mode: hardware_only %s(%d)\n", (rc == 0) ? "SUCCEEDED" : "FAILED", rc ); /* NOTE: - valid protocols: UDP or TCP */ perfect_rule = &rule.rule_family.perfect_rule; memset(&rule, 0, sizeof(rule)); rule.rule_family_type = intel_82599_perfect_filter_rule; rule.rule_id = rule_id++; perfect_rule->queue_id = queue; perfect_rule->proto = IPPROTO_UDP; perfect_rule->d_addr = ntohl(inet_addr(addr)); rc = pfring_add_hw_rule(thering, &rule); if(rc != 0) printf("pfring_add_hw_rule(%d) failed [rc=%d]: " "did you enable the FlowDirector " "(ethtool -K ethX ntuple on)\n", rule.rule_id, rc); else printf("pfring_add_hw_rule(%d) succeeded: " "steering UDP traffic %s:* -> *\n", rule.rule_id, addr); return rc; }
void pfring_hardware_filter_action_block(std::string client_ip_as_string) { /* 6 - tcp, 17 - udp, 0 - other (non tcp and non udp) */ std::vector<int> banned_protocols; banned_protocols.push_back(17); banned_protocols.push_back(6); banned_protocols.push_back(0); int rule_number = 10; // Iterate over incoming and outgoing direction for (int rule_direction = 0; rule_direction < 2; rule_direction++) { for (std::vector<int>::iterator banned_protocol = banned_protocols.begin(); banned_protocol != banned_protocols.end(); ++banned_protocol) { /* On 82599 NIC we can ban traffic using hardware filtering rules */ // Difference between fie tuple and perfect filters: // http://www.ntop.org/products/pf_ring/hardware-packet-filtering/ hw_filtering_rule rule; intel_82599_five_tuple_filter_hw_rule* ft_rule; ft_rule = &rule.rule_family.five_tuple_rule; memset(&rule, 0, sizeof(rule)); rule.rule_family_type = intel_82599_five_tuple_rule; rule.rule_id = rule_number++; ft_rule->queue_id = -1; // drop traffic ft_rule->proto = *banned_protocol; std::string hw_filter_rule_direction = ""; if (rule_direction == 0) { hw_filter_rule_direction = "outgoing"; ft_rule->s_addr = ntohl(inet_addr(client_ip_as_string.c_str())); } else { hw_filter_rule_direction = "incoming"; ft_rule->d_addr = ntohl(inet_addr(client_ip_as_string.c_str())); } if (pfring_add_hw_rule(pf_ring_descr, &rule) != 0) { logger << log4cpp::Priority::ERROR << "Can't add hardware filtering rule for protocol: " << *banned_protocol << " in direction: " << hw_filter_rule_direction; } rule_number++; } } }