net: prestera: add support for egress traffic mirroring
authorSerhiy Boiko <serhiy.boiko@plvision.eu>
Tue, 23 Aug 2022 11:39:57 +0000 (14:39 +0300)
committerDavid S. Miller <davem@davemloft.net>
Fri, 26 Aug 2022 09:04:54 +0000 (10:04 +0100)
This enables adding matchall rules for egress:

  tc filter add .. egress .. matchall skip_sw \
    action mirred egress mirror dev ..

Signed-off-by: Serhiy Boiko <serhiy.boiko@plvision.eu>
Signed-off-by: Maksym Glubokiy <maksym.glubokiy@plvision.eu>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/marvell/prestera/prestera_hw.c
drivers/net/ethernet/marvell/prestera/prestera_hw.h
drivers/net/ethernet/marvell/prestera/prestera_matchall.c
drivers/net/ethernet/marvell/prestera/prestera_span.c
drivers/net/ethernet/marvell/prestera/prestera_span.h

index 1a68a88..5803a28 100644 (file)
@@ -78,9 +78,11 @@ enum prestera_cmd_type_t {
        PRESTERA_CMD_TYPE_STP_PORT_SET = 0x1000,
 
        PRESTERA_CMD_TYPE_SPAN_GET = 0x1100,
-       PRESTERA_CMD_TYPE_SPAN_BIND = 0x1101,
-       PRESTERA_CMD_TYPE_SPAN_UNBIND = 0x1102,
+       PRESTERA_CMD_TYPE_SPAN_INGRESS_BIND = 0x1101,
+       PRESTERA_CMD_TYPE_SPAN_INGRESS_UNBIND = 0x1102,
        PRESTERA_CMD_TYPE_SPAN_RELEASE = 0x1103,
+       PRESTERA_CMD_TYPE_SPAN_EGRESS_BIND = 0x1104,
+       PRESTERA_CMD_TYPE_SPAN_EGRESS_UNBIND = 0x1105,
 
        PRESTERA_CMD_TYPE_POLICER_CREATE = 0x1500,
        PRESTERA_CMD_TYPE_POLICER_RELEASE = 0x1501,
@@ -1434,27 +1436,39 @@ int prestera_hw_span_get(const struct prestera_port *port, u8 *span_id)
        return 0;
 }
 
-int prestera_hw_span_bind(const struct prestera_port *port, u8 span_id)
+int prestera_hw_span_bind(const struct prestera_port *port, u8 span_id,
+                         bool ingress)
 {
        struct prestera_msg_span_req req = {
                .port = __cpu_to_le32(port->hw_id),
                .dev = __cpu_to_le32(port->dev_id),
                .id = span_id,
        };
+       enum prestera_cmd_type_t cmd_type;
+
+       if (ingress)
+               cmd_type = PRESTERA_CMD_TYPE_SPAN_INGRESS_BIND;
+       else
+               cmd_type = PRESTERA_CMD_TYPE_SPAN_EGRESS_BIND;
+
+       return prestera_cmd(port->sw, cmd_type, &req.cmd, sizeof(req));
 
-       return prestera_cmd(port->sw, PRESTERA_CMD_TYPE_SPAN_BIND,
-                           &req.cmd, sizeof(req));
 }
 
-int prestera_hw_span_unbind(const struct prestera_port *port)
+int prestera_hw_span_unbind(const struct prestera_port *port, bool ingress)
 {
        struct prestera_msg_span_req req = {
                .port = __cpu_to_le32(port->hw_id),
                .dev = __cpu_to_le32(port->dev_id),
        };
+       enum prestera_cmd_type_t cmd_type;
 
-       return prestera_cmd(port->sw, PRESTERA_CMD_TYPE_SPAN_UNBIND,
-                           &req.cmd, sizeof(req));
+       if (ingress)
+               cmd_type = PRESTERA_CMD_TYPE_SPAN_INGRESS_UNBIND;
+       else
+               cmd_type = PRESTERA_CMD_TYPE_SPAN_EGRESS_UNBIND;
+
+       return prestera_cmd(port->sw, cmd_type, &req.cmd, sizeof(req));
 }
 
 int prestera_hw_span_release(struct prestera_switch *sw, u8 span_id)
index 4aca43e..21078a2 100644 (file)
@@ -245,8 +245,9 @@ int prestera_hw_counter_clear(struct prestera_switch *sw, u32 block_id,
 
 /* SPAN API */
 int prestera_hw_span_get(const struct prestera_port *port, u8 *span_id);
-int prestera_hw_span_bind(const struct prestera_port *port, u8 span_id);
-int prestera_hw_span_unbind(const struct prestera_port *port);
+int prestera_hw_span_bind(const struct prestera_port *port, u8 span_id,
+                         bool ingress);
+int prestera_hw_span_unbind(const struct prestera_port *port, bool ingress);
 int prestera_hw_span_release(struct prestera_switch *sw, u8 span_id);
 
 /* Router API */
index 54573c6..3fc1317 100644 (file)
@@ -43,7 +43,7 @@ int prestera_mall_replace(struct prestera_flow_block *block,
        port = netdev_priv(act->dev);
 
        list_for_each_entry(binding, &block->binding_list, list) {
-               err = prestera_span_rule_add(binding, port);
+               err = prestera_span_rule_add(binding, port, block->ingress);
                if (err)
                        goto rollback;
        }
@@ -53,7 +53,7 @@ int prestera_mall_replace(struct prestera_flow_block *block,
 rollback:
        list_for_each_entry_continue_reverse(binding,
                                             &block->binding_list, list)
-               prestera_span_rule_del(binding);
+               prestera_span_rule_del(binding, block->ingress);
        return err;
 }
 
@@ -62,5 +62,6 @@ void prestera_mall_destroy(struct prestera_flow_block *block)
        struct prestera_flow_block_binding *binding;
 
        list_for_each_entry(binding, &block->binding_list, list)
-               prestera_span_rule_del(binding);
+               prestera_span_rule_del(binding, block->ingress);
+
 }
index 766413b..f0e9d6e 100644 (file)
@@ -121,7 +121,8 @@ static int prestera_span_put(struct prestera_switch *sw, u8 span_id)
 }
 
 int prestera_span_rule_add(struct prestera_flow_block_binding *binding,
-                          struct prestera_port *to_port)
+                          struct prestera_port *to_port,
+                          bool ingress)
 {
        struct prestera_switch *sw = binding->port->sw;
        u8 span_id;
@@ -135,7 +136,7 @@ int prestera_span_rule_add(struct prestera_flow_block_binding *binding,
        if (err)
                return err;
 
-       err = prestera_hw_span_bind(binding->port, span_id);
+       err = prestera_hw_span_bind(binding->port, span_id, ingress);
        if (err) {
                prestera_span_put(sw, span_id);
                return err;
@@ -145,11 +146,12 @@ int prestera_span_rule_add(struct prestera_flow_block_binding *binding,
        return 0;
 }
 
-int prestera_span_rule_del(struct prestera_flow_block_binding *binding)
+int prestera_span_rule_del(struct prestera_flow_block_binding *binding,
+                          bool ingress)
 {
        int err;
 
-       err = prestera_hw_span_unbind(binding->port);
+       err = prestera_hw_span_unbind(binding->port, ingress);
        if (err)
                return err;
 
index 4958ce8..493b685 100644 (file)
@@ -16,7 +16,9 @@ int prestera_span_init(struct prestera_switch *sw);
 void prestera_span_fini(struct prestera_switch *sw);
 
 int prestera_span_rule_add(struct prestera_flow_block_binding *binding,
-                          struct prestera_port *to_port);
-int prestera_span_rule_del(struct prestera_flow_block_binding *binding);
+                          struct prestera_port *to_port,
+                          bool ingress);
+int prestera_span_rule_del(struct prestera_flow_block_binding *binding,
+                          bool ingress);
 
 #endif /* _PRESTERA_SPAN_H_ */