Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

IB/mlx5: Add support to match inner packet fields

Add support to match packet fields which are tunneled,
i.e. support matching the header of the inner packet which is the result of
or bit operation of the original header and the IB_FLOW_SPEC_INNER type.

The combination of IB_FLOW_SPEC_INNER | IB_FLOW_SPEC_VXLAN_TUNNEL is not
needed to be checked, because the IB core has this check already.

Signed-off-by: Moses Reuben <mosesr@mellanox.com>
Reviewed-by: Maor Gottlieb <maorg@mellanox.com>
Signed-off-by: Leon Romanovsky <leon@kernel.org>
Signed-off-by: Doug Ledford <dledford@redhat.com>

authored by

Moses Reuben and committed by
Doug Ledford
2d1e697e fbf46860

+78 -53
+78 -53
drivers/infiniband/hw/mlx5/main.c
··· 1526 1526 MLX5_SET(fte_match_set_lyr_2_4, outer_v, ip_protocol, val); 1527 1527 } 1528 1528 1529 + static void set_flow_label(void *misc_c, void *misc_v, u8 mask, u8 val, 1530 + bool inner) 1531 + { 1532 + if (inner) { 1533 + MLX5_SET(fte_match_set_misc, 1534 + misc_c, inner_ipv6_flow_label, mask); 1535 + MLX5_SET(fte_match_set_misc, 1536 + misc_v, inner_ipv6_flow_label, val); 1537 + } else { 1538 + MLX5_SET(fte_match_set_misc, 1539 + misc_c, outer_ipv6_flow_label, mask); 1540 + MLX5_SET(fte_match_set_misc, 1541 + misc_v, outer_ipv6_flow_label, val); 1542 + } 1543 + } 1544 + 1529 1545 static void set_tos(void *outer_c, void *outer_v, u8 mask, u8 val) 1530 1546 { 1531 1547 MLX5_SET(fte_match_set_lyr_2_4, outer_c, ip_ecn, mask); ··· 1568 1552 static int parse_flow_attr(u32 *match_c, u32 *match_v, 1569 1553 const union ib_flow_spec *ib_spec) 1570 1554 { 1571 - void *outer_headers_c = MLX5_ADDR_OF(fte_match_param, match_c, 1572 - outer_headers); 1573 - void *outer_headers_v = MLX5_ADDR_OF(fte_match_param, match_v, 1574 - outer_headers); 1575 1555 void *misc_params_c = MLX5_ADDR_OF(fte_match_param, match_c, 1576 1556 misc_parameters); 1577 1557 void *misc_params_v = MLX5_ADDR_OF(fte_match_param, match_v, 1578 1558 misc_parameters); 1559 + void *headers_c; 1560 + void *headers_v; 1579 1561 1580 - switch (ib_spec->type) { 1562 + if (ib_spec->type & IB_FLOW_SPEC_INNER) { 1563 + headers_c = MLX5_ADDR_OF(fte_match_param, match_c, 1564 + inner_headers); 1565 + headers_v = MLX5_ADDR_OF(fte_match_param, match_v, 1566 + inner_headers); 1567 + } else { 1568 + headers_c = MLX5_ADDR_OF(fte_match_param, match_c, 1569 + outer_headers); 1570 + headers_v = MLX5_ADDR_OF(fte_match_param, match_v, 1571 + outer_headers); 1572 + } 1573 + 1574 + switch (ib_spec->type & ~IB_FLOW_SPEC_INNER) { 1581 1575 case IB_FLOW_SPEC_ETH: 1582 1576 if (FIELDS_NOT_SUPPORTED(ib_spec->eth.mask, LAST_ETH_FIELD)) 1583 1577 return -ENOTSUPP; 1584 1578 1585 - ether_addr_copy(MLX5_ADDR_OF(fte_match_set_lyr_2_4, outer_headers_c, 1579 + ether_addr_copy(MLX5_ADDR_OF(fte_match_set_lyr_2_4, headers_c, 1586 1580 dmac_47_16), 1587 1581 ib_spec->eth.mask.dst_mac); 1588 - ether_addr_copy(MLX5_ADDR_OF(fte_match_set_lyr_2_4, outer_headers_v, 1582 + ether_addr_copy(MLX5_ADDR_OF(fte_match_set_lyr_2_4, headers_v, 1589 1583 dmac_47_16), 1590 1584 ib_spec->eth.val.dst_mac); 1591 1585 1592 - ether_addr_copy(MLX5_ADDR_OF(fte_match_set_lyr_2_4, outer_headers_c, 1586 + ether_addr_copy(MLX5_ADDR_OF(fte_match_set_lyr_2_4, headers_c, 1593 1587 smac_47_16), 1594 1588 ib_spec->eth.mask.src_mac); 1595 - ether_addr_copy(MLX5_ADDR_OF(fte_match_set_lyr_2_4, outer_headers_v, 1589 + ether_addr_copy(MLX5_ADDR_OF(fte_match_set_lyr_2_4, headers_v, 1596 1590 smac_47_16), 1597 1591 ib_spec->eth.val.src_mac); 1598 1592 1599 1593 if (ib_spec->eth.mask.vlan_tag) { 1600 - MLX5_SET(fte_match_set_lyr_2_4, outer_headers_c, 1594 + MLX5_SET(fte_match_set_lyr_2_4, headers_c, 1601 1595 vlan_tag, 1); 1602 - MLX5_SET(fte_match_set_lyr_2_4, outer_headers_v, 1596 + MLX5_SET(fte_match_set_lyr_2_4, headers_v, 1603 1597 vlan_tag, 1); 1604 1598 1605 - MLX5_SET(fte_match_set_lyr_2_4, outer_headers_c, 1599 + MLX5_SET(fte_match_set_lyr_2_4, headers_c, 1606 1600 first_vid, ntohs(ib_spec->eth.mask.vlan_tag)); 1607 - MLX5_SET(fte_match_set_lyr_2_4, outer_headers_v, 1601 + MLX5_SET(fte_match_set_lyr_2_4, headers_v, 1608 1602 first_vid, ntohs(ib_spec->eth.val.vlan_tag)); 1609 1603 1610 - MLX5_SET(fte_match_set_lyr_2_4, outer_headers_c, 1604 + MLX5_SET(fte_match_set_lyr_2_4, headers_c, 1611 1605 first_cfi, 1612 1606 ntohs(ib_spec->eth.mask.vlan_tag) >> 12); 1613 - MLX5_SET(fte_match_set_lyr_2_4, outer_headers_v, 1607 + MLX5_SET(fte_match_set_lyr_2_4, headers_v, 1614 1608 first_cfi, 1615 1609 ntohs(ib_spec->eth.val.vlan_tag) >> 12); 1616 1610 1617 - MLX5_SET(fte_match_set_lyr_2_4, outer_headers_c, 1611 + MLX5_SET(fte_match_set_lyr_2_4, headers_c, 1618 1612 first_prio, 1619 1613 ntohs(ib_spec->eth.mask.vlan_tag) >> 13); 1620 - MLX5_SET(fte_match_set_lyr_2_4, outer_headers_v, 1614 + MLX5_SET(fte_match_set_lyr_2_4, headers_v, 1621 1615 first_prio, 1622 1616 ntohs(ib_spec->eth.val.vlan_tag) >> 13); 1623 1617 } 1624 - MLX5_SET(fte_match_set_lyr_2_4, outer_headers_c, 1618 + MLX5_SET(fte_match_set_lyr_2_4, headers_c, 1625 1619 ethertype, ntohs(ib_spec->eth.mask.ether_type)); 1626 - MLX5_SET(fte_match_set_lyr_2_4, outer_headers_v, 1620 + MLX5_SET(fte_match_set_lyr_2_4, headers_v, 1627 1621 ethertype, ntohs(ib_spec->eth.val.ether_type)); 1628 1622 break; 1629 1623 case IB_FLOW_SPEC_IPV4: 1630 1624 if (FIELDS_NOT_SUPPORTED(ib_spec->ipv4.mask, LAST_IPV4_FIELD)) 1631 1625 return -ENOTSUPP; 1632 1626 1633 - MLX5_SET(fte_match_set_lyr_2_4, outer_headers_c, 1627 + MLX5_SET(fte_match_set_lyr_2_4, headers_c, 1634 1628 ethertype, 0xffff); 1635 - MLX5_SET(fte_match_set_lyr_2_4, outer_headers_v, 1629 + MLX5_SET(fte_match_set_lyr_2_4, headers_v, 1636 1630 ethertype, ETH_P_IP); 1637 1631 1638 - memcpy(MLX5_ADDR_OF(fte_match_set_lyr_2_4, outer_headers_c, 1632 + memcpy(MLX5_ADDR_OF(fte_match_set_lyr_2_4, headers_c, 1639 1633 src_ipv4_src_ipv6.ipv4_layout.ipv4), 1640 1634 &ib_spec->ipv4.mask.src_ip, 1641 1635 sizeof(ib_spec->ipv4.mask.src_ip)); 1642 - memcpy(MLX5_ADDR_OF(fte_match_set_lyr_2_4, outer_headers_v, 1636 + memcpy(MLX5_ADDR_OF(fte_match_set_lyr_2_4, headers_v, 1643 1637 src_ipv4_src_ipv6.ipv4_layout.ipv4), 1644 1638 &ib_spec->ipv4.val.src_ip, 1645 1639 sizeof(ib_spec->ipv4.val.src_ip)); 1646 - memcpy(MLX5_ADDR_OF(fte_match_set_lyr_2_4, outer_headers_c, 1640 + memcpy(MLX5_ADDR_OF(fte_match_set_lyr_2_4, headers_c, 1647 1641 dst_ipv4_dst_ipv6.ipv4_layout.ipv4), 1648 1642 &ib_spec->ipv4.mask.dst_ip, 1649 1643 sizeof(ib_spec->ipv4.mask.dst_ip)); 1650 - memcpy(MLX5_ADDR_OF(fte_match_set_lyr_2_4, outer_headers_v, 1644 + memcpy(MLX5_ADDR_OF(fte_match_set_lyr_2_4, headers_v, 1651 1645 dst_ipv4_dst_ipv6.ipv4_layout.ipv4), 1652 1646 &ib_spec->ipv4.val.dst_ip, 1653 1647 sizeof(ib_spec->ipv4.val.dst_ip)); 1654 1648 1655 - set_tos(outer_headers_c, outer_headers_v, 1649 + set_tos(headers_c, headers_v, 1656 1650 ib_spec->ipv4.mask.tos, ib_spec->ipv4.val.tos); 1657 1651 1658 - set_proto(outer_headers_c, outer_headers_v, 1652 + set_proto(headers_c, headers_v, 1659 1653 ib_spec->ipv4.mask.proto, ib_spec->ipv4.val.proto); 1660 1654 break; 1661 1655 case IB_FLOW_SPEC_IPV6: 1662 1656 if (FIELDS_NOT_SUPPORTED(ib_spec->ipv6.mask, LAST_IPV6_FIELD)) 1663 1657 return -ENOTSUPP; 1664 1658 1665 - MLX5_SET(fte_match_set_lyr_2_4, outer_headers_c, 1659 + MLX5_SET(fte_match_set_lyr_2_4, headers_c, 1666 1660 ethertype, 0xffff); 1667 - MLX5_SET(fte_match_set_lyr_2_4, outer_headers_v, 1661 + MLX5_SET(fte_match_set_lyr_2_4, headers_v, 1668 1662 ethertype, ETH_P_IPV6); 1669 1663 1670 - memcpy(MLX5_ADDR_OF(fte_match_set_lyr_2_4, outer_headers_c, 1664 + memcpy(MLX5_ADDR_OF(fte_match_set_lyr_2_4, headers_c, 1671 1665 src_ipv4_src_ipv6.ipv6_layout.ipv6), 1672 1666 &ib_spec->ipv6.mask.src_ip, 1673 1667 sizeof(ib_spec->ipv6.mask.src_ip)); 1674 - memcpy(MLX5_ADDR_OF(fte_match_set_lyr_2_4, outer_headers_v, 1668 + memcpy(MLX5_ADDR_OF(fte_match_set_lyr_2_4, headers_v, 1675 1669 src_ipv4_src_ipv6.ipv6_layout.ipv6), 1676 1670 &ib_spec->ipv6.val.src_ip, 1677 1671 sizeof(ib_spec->ipv6.val.src_ip)); 1678 - memcpy(MLX5_ADDR_OF(fte_match_set_lyr_2_4, outer_headers_c, 1672 + memcpy(MLX5_ADDR_OF(fte_match_set_lyr_2_4, headers_c, 1679 1673 dst_ipv4_dst_ipv6.ipv6_layout.ipv6), 1680 1674 &ib_spec->ipv6.mask.dst_ip, 1681 1675 sizeof(ib_spec->ipv6.mask.dst_ip)); 1682 - memcpy(MLX5_ADDR_OF(fte_match_set_lyr_2_4, outer_headers_v, 1676 + memcpy(MLX5_ADDR_OF(fte_match_set_lyr_2_4, headers_v, 1683 1677 dst_ipv4_dst_ipv6.ipv6_layout.ipv6), 1684 1678 &ib_spec->ipv6.val.dst_ip, 1685 1679 sizeof(ib_spec->ipv6.val.dst_ip)); 1686 1680 1687 - set_tos(outer_headers_c, outer_headers_v, 1681 + set_tos(headers_c, headers_v, 1688 1682 ib_spec->ipv6.mask.traffic_class, 1689 1683 ib_spec->ipv6.val.traffic_class); 1690 1684 1691 - set_proto(outer_headers_c, outer_headers_v, 1685 + set_proto(headers_c, headers_v, 1692 1686 ib_spec->ipv6.mask.next_hdr, 1693 1687 ib_spec->ipv6.val.next_hdr); 1694 1688 1695 - MLX5_SET(fte_match_set_misc, misc_params_c, 1696 - outer_ipv6_flow_label, 1697 - ntohl(ib_spec->ipv6.mask.flow_label)); 1698 - MLX5_SET(fte_match_set_misc, misc_params_v, 1699 - outer_ipv6_flow_label, 1700 - ntohl(ib_spec->ipv6.val.flow_label)); 1689 + set_flow_label(misc_params_c, misc_params_v, 1690 + ntohl(ib_spec->ipv6.mask.flow_label), 1691 + ntohl(ib_spec->ipv6.val.flow_label), 1692 + ib_spec->type & IB_FLOW_SPEC_INNER); 1693 + 1701 1694 break; 1702 1695 case IB_FLOW_SPEC_TCP: 1703 1696 if (FIELDS_NOT_SUPPORTED(ib_spec->tcp_udp.mask, 1704 1697 LAST_TCP_UDP_FIELD)) 1705 1698 return -ENOTSUPP; 1706 1699 1707 - MLX5_SET(fte_match_set_lyr_2_4, outer_headers_c, ip_protocol, 1700 + MLX5_SET(fte_match_set_lyr_2_4, headers_c, ip_protocol, 1708 1701 0xff); 1709 - MLX5_SET(fte_match_set_lyr_2_4, outer_headers_v, ip_protocol, 1702 + MLX5_SET(fte_match_set_lyr_2_4, headers_v, ip_protocol, 1710 1703 IPPROTO_TCP); 1711 1704 1712 - MLX5_SET(fte_match_set_lyr_2_4, outer_headers_c, tcp_sport, 1705 + MLX5_SET(fte_match_set_lyr_2_4, headers_c, tcp_sport, 1713 1706 ntohs(ib_spec->tcp_udp.mask.src_port)); 1714 - MLX5_SET(fte_match_set_lyr_2_4, outer_headers_v, tcp_sport, 1707 + MLX5_SET(fte_match_set_lyr_2_4, headers_v, tcp_sport, 1715 1708 ntohs(ib_spec->tcp_udp.val.src_port)); 1716 1709 1717 - MLX5_SET(fte_match_set_lyr_2_4, outer_headers_c, tcp_dport, 1710 + MLX5_SET(fte_match_set_lyr_2_4, headers_c, tcp_dport, 1718 1711 ntohs(ib_spec->tcp_udp.mask.dst_port)); 1719 - MLX5_SET(fte_match_set_lyr_2_4, outer_headers_v, tcp_dport, 1712 + MLX5_SET(fte_match_set_lyr_2_4, headers_v, tcp_dport, 1720 1713 ntohs(ib_spec->tcp_udp.val.dst_port)); 1721 1714 break; 1722 1715 case IB_FLOW_SPEC_UDP: ··· 1733 1708 LAST_TCP_UDP_FIELD)) 1734 1709 return -ENOTSUPP; 1735 1710 1736 - MLX5_SET(fte_match_set_lyr_2_4, outer_headers_c, ip_protocol, 1711 + MLX5_SET(fte_match_set_lyr_2_4, headers_c, ip_protocol, 1737 1712 0xff); 1738 - MLX5_SET(fte_match_set_lyr_2_4, outer_headers_v, ip_protocol, 1713 + MLX5_SET(fte_match_set_lyr_2_4, headers_v, ip_protocol, 1739 1714 IPPROTO_UDP); 1740 1715 1741 - MLX5_SET(fte_match_set_lyr_2_4, outer_headers_c, udp_sport, 1716 + MLX5_SET(fte_match_set_lyr_2_4, headers_c, udp_sport, 1742 1717 ntohs(ib_spec->tcp_udp.mask.src_port)); 1743 - MLX5_SET(fte_match_set_lyr_2_4, outer_headers_v, udp_sport, 1718 + MLX5_SET(fte_match_set_lyr_2_4, headers_v, udp_sport, 1744 1719 ntohs(ib_spec->tcp_udp.val.src_port)); 1745 1720 1746 - MLX5_SET(fte_match_set_lyr_2_4, outer_headers_c, udp_dport, 1721 + MLX5_SET(fte_match_set_lyr_2_4, headers_c, udp_dport, 1747 1722 ntohs(ib_spec->tcp_udp.mask.dst_port)); 1748 - MLX5_SET(fte_match_set_lyr_2_4, outer_headers_v, udp_dport, 1723 + MLX5_SET(fte_match_set_lyr_2_4, headers_v, udp_dport, 1749 1724 ntohs(ib_spec->tcp_udp.val.dst_port)); 1750 1725 break; 1751 1726 case IB_FLOW_SPEC_VXLAN_TUNNEL: