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: Serhiy Boiko <serhiy.boiko@plvision.eu> Signed-off-by: Maksym Glubokiy <maksym.glubokiy@plvision.eu> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
8afd552db4
commit
8c448c2b5f
|
@ -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)
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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_ */
|
||||
|
|
Loading…
Reference in New Issue