Commit 8c448c2b authored by Serhiy Boiko's avatar Serhiy Boiko Committed by David S. Miller

net: prestera: add support for egress traffic mirroring

This enables adding matchall rules for egress:

  tc filter add .. egress .. matchall skip_sw \
    action mirred egress mirror dev ..
Signed-off-by: default avatarSerhiy Boiko <serhiy.boiko@plvision.eu>
Signed-off-by: default avatarMaksym Glubokiy <maksym.glubokiy@plvision.eu>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 8afd552d
...@@ -78,9 +78,11 @@ enum prestera_cmd_type_t { ...@@ -78,9 +78,11 @@ enum prestera_cmd_type_t {
PRESTERA_CMD_TYPE_STP_PORT_SET = 0x1000, PRESTERA_CMD_TYPE_STP_PORT_SET = 0x1000,
PRESTERA_CMD_TYPE_SPAN_GET = 0x1100, PRESTERA_CMD_TYPE_SPAN_GET = 0x1100,
PRESTERA_CMD_TYPE_SPAN_BIND = 0x1101, PRESTERA_CMD_TYPE_SPAN_INGRESS_BIND = 0x1101,
PRESTERA_CMD_TYPE_SPAN_UNBIND = 0x1102, PRESTERA_CMD_TYPE_SPAN_INGRESS_UNBIND = 0x1102,
PRESTERA_CMD_TYPE_SPAN_RELEASE = 0x1103, 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_CREATE = 0x1500,
PRESTERA_CMD_TYPE_POLICER_RELEASE = 0x1501, PRESTERA_CMD_TYPE_POLICER_RELEASE = 0x1501,
...@@ -1434,27 +1436,39 @@ int prestera_hw_span_get(const struct prestera_port *port, u8 *span_id) ...@@ -1434,27 +1436,39 @@ int prestera_hw_span_get(const struct prestera_port *port, u8 *span_id)
return 0; 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 = { struct prestera_msg_span_req req = {
.port = __cpu_to_le32(port->hw_id), .port = __cpu_to_le32(port->hw_id),
.dev = __cpu_to_le32(port->dev_id), .dev = __cpu_to_le32(port->dev_id),
.id = span_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 = { struct prestera_msg_span_req req = {
.port = __cpu_to_le32(port->hw_id), .port = __cpu_to_le32(port->hw_id),
.dev = __cpu_to_le32(port->dev_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, if (ingress)
&req.cmd, sizeof(req)); 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) int prestera_hw_span_release(struct prestera_switch *sw, u8 span_id)
......
...@@ -245,8 +245,9 @@ int prestera_hw_counter_clear(struct prestera_switch *sw, u32 block_id, ...@@ -245,8 +245,9 @@ int prestera_hw_counter_clear(struct prestera_switch *sw, u32 block_id,
/* SPAN API */ /* SPAN API */
int prestera_hw_span_get(const struct prestera_port *port, u8 *span_id); 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_bind(const struct prestera_port *port, u8 span_id,
int prestera_hw_span_unbind(const struct prestera_port *port); 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); int prestera_hw_span_release(struct prestera_switch *sw, u8 span_id);
/* Router API */ /* Router API */
......
...@@ -43,7 +43,7 @@ int prestera_mall_replace(struct prestera_flow_block *block, ...@@ -43,7 +43,7 @@ int prestera_mall_replace(struct prestera_flow_block *block,
port = netdev_priv(act->dev); port = netdev_priv(act->dev);
list_for_each_entry(binding, &block->binding_list, list) { 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) if (err)
goto rollback; goto rollback;
} }
...@@ -53,7 +53,7 @@ int prestera_mall_replace(struct prestera_flow_block *block, ...@@ -53,7 +53,7 @@ int prestera_mall_replace(struct prestera_flow_block *block,
rollback: rollback:
list_for_each_entry_continue_reverse(binding, list_for_each_entry_continue_reverse(binding,
&block->binding_list, list) &block->binding_list, list)
prestera_span_rule_del(binding); prestera_span_rule_del(binding, block->ingress);
return err; return err;
} }
...@@ -62,5 +62,6 @@ void prestera_mall_destroy(struct prestera_flow_block *block) ...@@ -62,5 +62,6 @@ void prestera_mall_destroy(struct prestera_flow_block *block)
struct prestera_flow_block_binding *binding; struct prestera_flow_block_binding *binding;
list_for_each_entry(binding, &block->binding_list, list) list_for_each_entry(binding, &block->binding_list, list)
prestera_span_rule_del(binding); prestera_span_rule_del(binding, block->ingress);
} }
...@@ -121,7 +121,8 @@ static int prestera_span_put(struct prestera_switch *sw, u8 span_id) ...@@ -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, 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; struct prestera_switch *sw = binding->port->sw;
u8 span_id; u8 span_id;
...@@ -135,7 +136,7 @@ int prestera_span_rule_add(struct prestera_flow_block_binding *binding, ...@@ -135,7 +136,7 @@ int prestera_span_rule_add(struct prestera_flow_block_binding *binding,
if (err) if (err)
return err; return err;
err = prestera_hw_span_bind(binding->port, span_id); err = prestera_hw_span_bind(binding->port, span_id, ingress);
if (err) { if (err) {
prestera_span_put(sw, span_id); prestera_span_put(sw, span_id);
return err; return err;
...@@ -145,11 +146,12 @@ int prestera_span_rule_add(struct prestera_flow_block_binding *binding, ...@@ -145,11 +146,12 @@ int prestera_span_rule_add(struct prestera_flow_block_binding *binding,
return 0; 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; int err;
err = prestera_hw_span_unbind(binding->port); err = prestera_hw_span_unbind(binding->port, ingress);
if (err) if (err)
return err; return err;
......
...@@ -16,7 +16,9 @@ int prestera_span_init(struct prestera_switch *sw); ...@@ -16,7 +16,9 @@ int prestera_span_init(struct prestera_switch *sw);
void prestera_span_fini(struct prestera_switch *sw); void prestera_span_fini(struct prestera_switch *sw);
int prestera_span_rule_add(struct prestera_flow_block_binding *binding, int prestera_span_rule_add(struct prestera_flow_block_binding *binding,
struct prestera_port *to_port); struct prestera_port *to_port,
int prestera_span_rule_del(struct prestera_flow_block_binding *binding); bool ingress);
int prestera_span_rule_del(struct prestera_flow_block_binding *binding,
bool ingress);
#endif /* _PRESTERA_SPAN_H_ */ #endif /* _PRESTERA_SPAN_H_ */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment