/** * iavf_validate_fdir_fltr_masks - validate Flow Director filter fields masks * @adapter: pointer to the VF adapter structure * @fltr: Flow Director filter data structure * * Returns 0 if all masks of packet fields are either full or empty. Returns * error on at least one partial mask.
*/ int iavf_validate_fdir_fltr_masks(struct iavf_adapter *adapter, struct iavf_fdir_fltr *fltr)
{ if (fltr->eth_mask.etype && fltr->eth_mask.etype != htons(U16_MAX)) goto partial_mask;
if (fltr->ip_ver == 4) { if (fltr->ip_mask.v4_addrs.src_ip &&
fltr->ip_mask.v4_addrs.src_ip != htonl(U32_MAX)) goto partial_mask;
if (fltr->ip_mask.v4_addrs.dst_ip &&
fltr->ip_mask.v4_addrs.dst_ip != htonl(U32_MAX)) goto partial_mask;
uhdr->field_selector = 0; /* The PF ignores the UDP header fields */
return 0;
}
/** * iavf_fill_fdir_udp_flex_pay_hdr - fill the UDP payload header * @fltr: Flow Director filter data structure * @proto_hdrs: Flow Director protocol headers data structure * * Returns 0 if the UDP payload defined protocol header is set successfully
*/ staticint
iavf_fill_fdir_udp_flex_pay_hdr(struct iavf_fdir_fltr *fltr, struct virtchnl_proto_hdrs *proto_hdrs)
{ int err;
switch (ntohs(fltr->ip_data.dst_port)) { case GTPU_PORT:
err = iavf_fill_fdir_gtpu_hdr(fltr, proto_hdrs); break; case NAT_T_ESP_PORT:
err = iavf_fill_fdir_nat_t_esp_hdr(fltr, proto_hdrs); break; case PFCP_PORT:
err = iavf_fill_fdir_pfcp_hdr(fltr, proto_hdrs); break; default:
err = -EOPNOTSUPP; break;
}
return err;
}
/** * iavf_fill_fdir_ip4_hdr - fill the IPv4 protocol header * @fltr: Flow Director filter data structure * @proto_hdrs: Flow Director protocol headers data structure * * Returns 0 if the IPv4 protocol header is set successfully
*/ staticint
iavf_fill_fdir_ip4_hdr(struct iavf_fdir_fltr *fltr, struct virtchnl_proto_hdrs *proto_hdrs)
{ struct virtchnl_proto_hdr *hdr = &proto_hdrs->proto_hdr[proto_hdrs->count++]; struct iphdr *iph = (struct iphdr *)hdr->buffer;
/** * iavf_fill_fdir_l4_hdr - fill the L4 protocol header * @fltr: Flow Director filter data structure * @proto_hdrs: Flow Director protocol headers data structure * * Returns 0 if the L4 protocol header is set successfully
*/ staticint
iavf_fill_fdir_l4_hdr(struct iavf_fdir_fltr *fltr, struct virtchnl_proto_hdrs *proto_hdrs)
{ struct virtchnl_proto_hdr *hdr;
__be32 *l4_4_data;
if (!fltr->ip_mask.proto) /* IPv4/IPv6 header only */ return 0;
/** * iavf_fill_fdir_add_msg - fill the Flow Director filter into virtchnl message * @adapter: pointer to the VF adapter structure * @fltr: Flow Director filter data structure * * Returns 0 if the add Flow Director virtchnl message is filled successfully
*/ int iavf_fill_fdir_add_msg(struct iavf_adapter *adapter, struct iavf_fdir_fltr *fltr)
{ struct virtchnl_fdir_add *vc_msg = &fltr->vc_add_msg; struct virtchnl_proto_hdrs *proto_hdrs; int err;
/** * iavf_fdir_flow_proto_name - get the flow protocol name * @flow_type: Flow Director filter flow type
**/ staticconstchar *iavf_fdir_flow_proto_name(enum iavf_fdir_flow_type flow_type)
{ switch (flow_type) { case IAVF_FDIR_FLOW_IPV4_TCP: case IAVF_FDIR_FLOW_IPV6_TCP: return"TCP"; case IAVF_FDIR_FLOW_IPV4_UDP: case IAVF_FDIR_FLOW_IPV6_UDP: return"UDP"; case IAVF_FDIR_FLOW_IPV4_SCTP: case IAVF_FDIR_FLOW_IPV6_SCTP: return"SCTP"; case IAVF_FDIR_FLOW_IPV4_AH: case IAVF_FDIR_FLOW_IPV6_AH: return"AH"; case IAVF_FDIR_FLOW_IPV4_ESP: case IAVF_FDIR_FLOW_IPV6_ESP: return"ESP"; case IAVF_FDIR_FLOW_IPV4_OTHER: case IAVF_FDIR_FLOW_IPV6_OTHER: return"Other"; case IAVF_FDIR_FLOW_NON_IP_L2: return"Ethernet"; default: return NULL;
}
}
/** * iavf_print_fdir_fltr * @adapter: adapter structure * @fltr: Flow Director filter to print * * Print the Flow Director filter
**/ void iavf_print_fdir_fltr(struct iavf_adapter *adapter, struct iavf_fdir_fltr *fltr)
{ constchar *proto = iavf_fdir_flow_proto_name(fltr->flow_type);
if (!proto) return;
switch (fltr->flow_type) { case IAVF_FDIR_FLOW_IPV4_TCP: case IAVF_FDIR_FLOW_IPV4_UDP: case IAVF_FDIR_FLOW_IPV4_SCTP:
dev_info(&adapter->pdev->dev, "Rule ID: %u dst_ip: %pI4 src_ip %pI4 %s: dst_port %hu src_port %hu\n",
fltr->loc,
&fltr->ip_data.v4_addrs.dst_ip,
&fltr->ip_data.v4_addrs.src_ip,
proto,
ntohs(fltr->ip_data.dst_port),
ntohs(fltr->ip_data.src_port)); break; case IAVF_FDIR_FLOW_IPV4_AH: case IAVF_FDIR_FLOW_IPV4_ESP:
dev_info(&adapter->pdev->dev, "Rule ID: %u dst_ip: %pI4 src_ip %pI4 %s: SPI %u\n",
fltr->loc,
&fltr->ip_data.v4_addrs.dst_ip,
&fltr->ip_data.v4_addrs.src_ip,
proto,
ntohl(fltr->ip_data.spi)); break; case IAVF_FDIR_FLOW_IPV4_OTHER:
dev_info(&adapter->pdev->dev, "Rule ID: %u dst_ip: %pI4 src_ip %pI4 proto: %u L4_bytes: 0x%x\n",
fltr->loc,
&fltr->ip_data.v4_addrs.dst_ip,
&fltr->ip_data.v4_addrs.src_ip,
fltr->ip_data.proto,
ntohl(fltr->ip_data.l4_header)); break; case IAVF_FDIR_FLOW_IPV6_TCP: case IAVF_FDIR_FLOW_IPV6_UDP: case IAVF_FDIR_FLOW_IPV6_SCTP:
dev_info(&adapter->pdev->dev, "Rule ID: %u dst_ip: %pI6 src_ip %pI6 %s: dst_port %hu src_port %hu\n",
fltr->loc,
&fltr->ip_data.v6_addrs.dst_ip,
&fltr->ip_data.v6_addrs.src_ip,
proto,
ntohs(fltr->ip_data.dst_port),
ntohs(fltr->ip_data.src_port)); break; case IAVF_FDIR_FLOW_IPV6_AH: case IAVF_FDIR_FLOW_IPV6_ESP:
dev_info(&adapter->pdev->dev, "Rule ID: %u dst_ip: %pI6 src_ip %pI6 %s: SPI %u\n",
fltr->loc,
&fltr->ip_data.v6_addrs.dst_ip,
&fltr->ip_data.v6_addrs.src_ip,
proto,
ntohl(fltr->ip_data.spi)); break; case IAVF_FDIR_FLOW_IPV6_OTHER:
dev_info(&adapter->pdev->dev, "Rule ID: %u dst_ip: %pI6 src_ip %pI6 proto: %u L4_bytes: 0x%x\n",
fltr->loc,
&fltr->ip_data.v6_addrs.dst_ip,
&fltr->ip_data.v6_addrs.src_ip,
fltr->ip_data.proto,
ntohl(fltr->ip_data.l4_header)); break; case IAVF_FDIR_FLOW_NON_IP_L2:
dev_info(&adapter->pdev->dev, "Rule ID: %u eth_type: 0x%x\n",
fltr->loc,
ntohs(fltr->eth_data.etype)); break; default: break;
}
}
/** * iavf_fdir_is_dup_fltr - test if filter is already in list * @adapter: pointer to the VF adapter structure * @fltr: Flow Director filter data structure * * Returns true if the filter is found in the list
*/ bool iavf_fdir_is_dup_fltr(struct iavf_adapter *adapter, struct iavf_fdir_fltr *fltr)
{ struct iavf_fdir_fltr *tmp; bool ret = false;
spin_lock_bh(&adapter->fdir_fltr_lock);
list_for_each_entry(tmp, &adapter->fdir_list_head, list) { if (iavf_is_raw_fdir(fltr)) continue;
if (tmp->flow_type != fltr->flow_type) continue;
if (!memcmp(&tmp->eth_data, &fltr->eth_data, sizeof(fltr->eth_data)) &&
!memcmp(&tmp->ip_data, &fltr->ip_data, sizeof(fltr->ip_data)) &&
!memcmp(&tmp->ext_data, &fltr->ext_data, sizeof(fltr->ext_data))) {
ret = true; break;
}
}
spin_unlock_bh(&adapter->fdir_fltr_lock);
return ret;
}
/** * iavf_find_fdir_fltr - find FDIR filter * @adapter: pointer to the VF adapter structure * @is_raw: filter type, is raw (tc u32) or not (ethtool) * @data: data to ID the filter, type dependent * * Returns: pointer to Flow Director filter if found or NULL. Lock must be held.
*/ struct iavf_fdir_fltr *iavf_find_fdir_fltr(struct iavf_adapter *adapter, bool is_raw, u32 data)
{ struct iavf_fdir_fltr *rule;
/** * iavf_fdir_add_fltr - add a new node to the flow director filter list * @adapter: pointer to the VF adapter structure * @fltr: filter node to add to structure * * Return: 0 on success or negative errno on failure.
*/ int iavf_fdir_add_fltr(struct iavf_adapter *adapter, struct iavf_fdir_fltr *fltr)
{ struct iavf_fdir_fltr *rule, *parent = NULL;
spin_lock_bh(&adapter->fdir_fltr_lock); if (iavf_fdir_max_reached(adapter)) {
spin_unlock_bh(&adapter->fdir_fltr_lock);
dev_err(&adapter->pdev->dev, "Unable to add Flow Director filter (limit (%u) reached)\n",
IAVF_MAX_FDIR_FILTERS); return -ENOSPC;
}
list_for_each_entry(rule, &adapter->fdir_list_head, list) { if (iavf_is_raw_fdir(fltr)) break;
if (rule->loc >= fltr->loc) break;
parent = rule;
}
if (parent)
list_add(&fltr->list, &parent->list); else
list_add(&fltr->list, &adapter->fdir_list_head);
iavf_inc_fdir_active_fltr(adapter, fltr);
if (adapter->link_up)
fltr->state = IAVF_FDIR_FLTR_ADD_REQUEST; else
fltr->state = IAVF_FDIR_FLTR_INACTIVE;
spin_unlock_bh(&adapter->fdir_fltr_lock);
if (adapter->link_up)
iavf_schedule_aq_request(adapter, IAVF_FLAG_AQ_ADD_FDIR_FILTER);
return 0;
}
/** * iavf_fdir_del_fltr - delete a flow director filter from the list * @adapter: pointer to the VF adapter structure * @is_raw: filter type, is raw (tc u32) or not (ethtool) * @data: data to ID the filter, type dependent * * Return: 0 on success or negative errno on failure.
*/ int iavf_fdir_del_fltr(struct iavf_adapter *adapter, bool is_raw, u32 data)
{ struct iavf_fdir_fltr *fltr = NULL; int err = 0;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.