]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
qede: Add destination ip based flow profile.
authorManish Chopra <manish.chopra@cavium.com>
Thu, 9 Aug 2018 18:13:50 +0000 (11:13 -0700)
committerDavid S. Miller <davem@davemloft.net>
Thu, 9 Aug 2018 21:05:30 +0000 (14:05 -0700)
This patch adds support for dropping and redirecting
the flows based on destination IP in the packet.

This also moves the profile mode settings in their own
functions which can be used through tc flows in successive
patch.

For example -

ethtool -N p5p1 flow-type tcp4 dst-ip 192.168.40.100 action -1
ethtool -N p5p1 flow-type udp4 dst-ip 192.168.50.100 action 1
ethtool -N p5p1 flow-type tcp4 dst-ip 192.168.60.100 action 0x100000000

Signed-off-by: Manish Chopra <manish.chopra@cavium.com>
Signed-off-by: Ariel Elior <ariel.elior@cavium.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/qlogic/qede/qede_filter.c

index f9a327c821eb608eae5743250bb0dbc55bb1fc2f..d0902573f38a894a5c8d1d4ee2c48dc4f99ffc58 100644 (file)
@@ -1599,6 +1599,69 @@ static int qede_flow_spec_validate_unused(struct qede_dev *edev,
        return 0;
 }
 
+static int qede_set_v4_tuple_to_profile(struct qede_dev *edev,
+                                       struct qede_arfs_tuple *t)
+{
+       /* We must have Only 4-tuples/l4 port/src ip/dst ip
+        * as an input.
+        */
+       if (t->src_port && t->dst_port && t->src_ipv4 && t->dst_ipv4) {
+               t->mode = QED_FILTER_CONFIG_MODE_5_TUPLE;
+       } else if (!t->src_port && t->dst_port &&
+                  !t->src_ipv4 && !t->dst_ipv4) {
+               t->mode = QED_FILTER_CONFIG_MODE_L4_PORT;
+       } else if (!t->src_port && !t->dst_port &&
+                  !t->dst_ipv4 && t->src_ipv4) {
+               t->mode = QED_FILTER_CONFIG_MODE_IP_SRC;
+       } else if (!t->src_port && !t->dst_port &&
+                  t->dst_ipv4 && !t->src_ipv4) {
+               t->mode = QED_FILTER_CONFIG_MODE_IP_DEST;
+       } else {
+               DP_INFO(edev, "Invalid N-tuple\n");
+               return -EOPNOTSUPP;
+       }
+
+       t->ip_comp = qede_flow_spec_ipv4_cmp;
+       t->build_hdr = qede_flow_build_ipv4_hdr;
+       t->stringify = qede_flow_stringify_ipv4_hdr;
+
+       return 0;
+}
+
+static int qede_set_v6_tuple_to_profile(struct qede_dev *edev,
+                                       struct qede_arfs_tuple *t,
+                                       struct in6_addr *zaddr)
+{
+       /* We must have Only 4-tuples/l4 port/src ip/dst ip
+        * as an input.
+        */
+       if (t->src_port && t->dst_port &&
+           memcmp(&t->src_ipv6, zaddr, sizeof(struct in6_addr)) &&
+           memcmp(&t->dst_ipv6, zaddr, sizeof(struct in6_addr))) {
+               t->mode = QED_FILTER_CONFIG_MODE_5_TUPLE;
+       } else if (!t->src_port && t->dst_port &&
+                  !memcmp(&t->src_ipv6, zaddr, sizeof(struct in6_addr)) &&
+                  !memcmp(&t->dst_ipv6, zaddr, sizeof(struct in6_addr))) {
+               t->mode = QED_FILTER_CONFIG_MODE_L4_PORT;
+       } else if (!t->src_port && !t->dst_port &&
+                  !memcmp(&t->dst_ipv6, zaddr, sizeof(struct in6_addr)) &&
+                  memcmp(&t->src_ipv6, zaddr, sizeof(struct in6_addr))) {
+               t->mode = QED_FILTER_CONFIG_MODE_IP_SRC;
+       } else if (!t->src_port && !t->dst_port &&
+                  memcmp(&t->dst_ipv6, zaddr, sizeof(struct in6_addr)) &&
+                  !memcmp(&t->src_ipv6, zaddr, sizeof(struct in6_addr))) {
+               t->mode = QED_FILTER_CONFIG_MODE_IP_DEST;
+       } else {
+               DP_INFO(edev, "Invalid N-tuple\n");
+               return -EOPNOTSUPP;
+       }
+
+       t->ip_comp = qede_flow_spec_ipv6_cmp;
+       t->build_hdr = qede_flow_build_ipv6_hdr;
+
+       return 0;
+}
+
 static int qede_flow_spec_to_tuple_ipv4_common(struct qede_dev *edev,
                                               struct qede_arfs_tuple *t,
                                               struct ethtool_rx_flow_spec *fs)
@@ -1638,27 +1701,7 @@ static int qede_flow_spec_to_tuple_ipv4_common(struct qede_dev *edev,
        t->src_port = fs->h_u.tcp_ip4_spec.psrc;
        t->dst_port = fs->h_u.tcp_ip4_spec.pdst;
 
-       /* We must either have a valid 4-tuple or only dst port
-        * or only src ip as an input
-        */
-       if (t->src_port && t->dst_port && t->src_ipv4 && t->dst_ipv4) {
-               t->mode = QED_FILTER_CONFIG_MODE_5_TUPLE;
-       } else if (!t->src_port && t->dst_port &&
-                  !t->src_ipv4 && !t->dst_ipv4) {
-               t->mode = QED_FILTER_CONFIG_MODE_L4_PORT;
-       }  else if (!t->src_port && !t->dst_port &&
-                   !t->dst_ipv4 && t->src_ipv4) {
-               t->mode = QED_FILTER_CONFIG_MODE_IP_SRC;
-       } else {
-               DP_INFO(edev, "Invalid N-tuple\n");
-               return -EOPNOTSUPP;
-       }
-
-       t->ip_comp = qede_flow_spec_ipv4_cmp;
-       t->build_hdr = qede_flow_build_ipv4_hdr;
-       t->stringify = qede_flow_stringify_ipv4_hdr;
-
-       return 0;
+       return qede_set_v4_tuple_to_profile(edev, t);
 }
 
 static int qede_flow_spec_to_tuple_tcpv4(struct qede_dev *edev,
@@ -1690,10 +1733,8 @@ static int qede_flow_spec_to_tuple_ipv6_common(struct qede_dev *edev,
                                               struct ethtool_rx_flow_spec *fs)
 {
        struct in6_addr zero_addr;
-       void *p;
 
-       p = &zero_addr;
-       memset(p, 0, sizeof(zero_addr));
+       memset(&zero_addr, 0, sizeof(zero_addr));
 
        if ((fs->h_u.tcp_ip6_spec.psrc &
             fs->m_u.tcp_ip6_spec.psrc) != fs->h_u.tcp_ip6_spec.psrc) {
@@ -1720,30 +1761,7 @@ static int qede_flow_spec_to_tuple_ipv6_common(struct qede_dev *edev,
        t->src_port = fs->h_u.tcp_ip6_spec.psrc;
        t->dst_port = fs->h_u.tcp_ip6_spec.pdst;
 
-       /* We must make sure we have a valid 4-tuple or only dest port
-        * or only src ip as an input
-        */
-       if (t->src_port && t->dst_port &&
-           memcmp(&t->src_ipv6, p, sizeof(struct in6_addr)) &&
-           memcmp(&t->dst_ipv6, p, sizeof(struct in6_addr))) {
-               t->mode = QED_FILTER_CONFIG_MODE_5_TUPLE;
-       } else if (!t->src_port && t->dst_port &&
-                  !memcmp(&t->src_ipv6, p, sizeof(struct in6_addr)) &&
-                  !memcmp(&t->dst_ipv6, p, sizeof(struct in6_addr))) {
-               t->mode = QED_FILTER_CONFIG_MODE_L4_PORT;
-       } else if (!t->src_port && !t->dst_port &&
-                  !memcmp(&t->dst_ipv6, p, sizeof(struct in6_addr)) &&
-                  memcmp(&t->src_ipv6, p, sizeof(struct in6_addr))) {
-               t->mode = QED_FILTER_CONFIG_MODE_IP_SRC;
-       } else {
-               DP_INFO(edev, "Invalid N-tuple\n");
-               return -EOPNOTSUPP;
-       }
-
-       t->ip_comp = qede_flow_spec_ipv6_cmp;
-       t->build_hdr = qede_flow_build_ipv6_hdr;
-
-       return 0;
+       return qede_set_v6_tuple_to_profile(edev, t, &zero_addr);
 }
 
 static int qede_flow_spec_to_tuple_tcpv6(struct qede_dev *edev,