OSDN Git Service

mlxsw: spectrum: Add definition for egress rif table
authorArkadi Sharshevsky <arkadis@mellanox.com>
Tue, 28 Mar 2017 15:24:13 +0000 (17:24 +0200)
committerDavid S. Miller <davem@davemloft.net>
Wed, 29 Mar 2017 00:11:54 +0000 (17:11 -0700)
Add definition for egress router interface table. This table describes
the final part in the routing pipeline. This table matches the egress
interface index (rif index, which is set by the previous stages and
determine the out port) and makes the decision of forwarding the packet
towards the L2 logic or dropping it.

The metadata header is added to represent this internal information.
The rif index field is mapped logically to netdevice ifindex.

Signed-off-by: Arkadi Sharshevsky <arkadis@mellanox.com>
Signed-off-by: Jiri Pirko <jiri@mellanox.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/mellanox/mlxsw/spectrum_dpipe.c
drivers/net/ethernet/mellanox/mlxsw/spectrum_dpipe.h

index 7c87bc8..5dde222 100644 (file)
 #include "spectrum.h"
 #include "spectrum_dpipe.h"
 
-static struct devlink_dpipe_header *mlxsw_dpipe_headers[] = {};
+enum mlxsw_sp_field_metadata_id {
+       MLXSW_SP_DPIPE_FIELD_METADATA_ERIF_PORT,
+       MLXSW_SP_DPIPE_FIELD_METADATA_L3_FORWARD,
+       MLXSW_SP_DPIPE_FIELD_METADATA_L3_DROP,
+};
+
+static struct devlink_dpipe_field mlxsw_sp_dpipe_fields_metadata[] = {
+       { .name = "erif_port",
+         .id = MLXSW_SP_DPIPE_FIELD_METADATA_ERIF_PORT,
+         .bitwidth = 32,
+         .mapping_type = DEVLINK_DPIPE_FIELD_MAPPING_TYPE_IFINDEX,
+       },
+       { .name = "l3_forward",
+         .id = MLXSW_SP_DPIPE_FIELD_METADATA_L3_FORWARD,
+         .bitwidth = 1,
+       },
+       { .name = "l3_drop",
+         .id = MLXSW_SP_DPIPE_FIELD_METADATA_L3_DROP,
+         .bitwidth = 1,
+       },
+};
+
+enum mlxsw_sp_dpipe_header_id {
+       MLXSW_SP_DPIPE_HEADER_METADATA,
+};
+
+static struct devlink_dpipe_header mlxsw_sp_dpipe_header_metadata = {
+       .name = "mlxsw_meta",
+       .id = MLXSW_SP_DPIPE_HEADER_METADATA,
+       .fields = mlxsw_sp_dpipe_fields_metadata,
+       .fields_count = ARRAY_SIZE(mlxsw_sp_dpipe_fields_metadata),
+};
+
+static struct devlink_dpipe_header *mlxsw_dpipe_headers[] = {
+       &mlxsw_sp_dpipe_header_metadata,
+};
 
 static struct devlink_dpipe_headers mlxsw_sp_dpipe_headers = {
        .headers = mlxsw_dpipe_headers,
        .headers_count = ARRAY_SIZE(mlxsw_dpipe_headers),
 };
 
+static int mlxsw_sp_dpipe_table_erif_actions_dump(void *priv,
+                                                 struct sk_buff *skb)
+{
+       struct devlink_dpipe_action action = {0};
+       int err;
+
+       action.type = DEVLINK_DPIPE_ACTION_TYPE_FIELD_MODIFY;
+       action.header = &mlxsw_sp_dpipe_header_metadata;
+       action.field_id = MLXSW_SP_DPIPE_FIELD_METADATA_L3_FORWARD;
+
+       err = devlink_dpipe_action_put(skb, &action);
+       if (err)
+               return err;
+
+       action.type = DEVLINK_DPIPE_ACTION_TYPE_FIELD_MODIFY;
+       action.header = &mlxsw_sp_dpipe_header_metadata;
+       action.field_id = MLXSW_SP_DPIPE_FIELD_METADATA_L3_DROP;
+
+       return devlink_dpipe_action_put(skb, &action);
+}
+
+static int mlxsw_sp_dpipe_table_erif_matches_dump(void *priv,
+                                                 struct sk_buff *skb)
+{
+       struct devlink_dpipe_match match = {0};
+
+       match.type = DEVLINK_DPIPE_MATCH_TYPE_FIELD_EXACT;
+       match.header = &mlxsw_sp_dpipe_header_metadata;
+       match.field_id = MLXSW_SP_DPIPE_FIELD_METADATA_ERIF_PORT;
+
+       return devlink_dpipe_match_put(skb, &match);
+}
+
+static struct devlink_dpipe_table_ops mlxsw_sp_erif_ops = {
+       .matches_dump = mlxsw_sp_dpipe_table_erif_matches_dump,
+       .actions_dump = mlxsw_sp_dpipe_table_erif_actions_dump,
+};
+
+static int mlxsw_sp_dpipe_erif_table_init(struct mlxsw_sp *mlxsw_sp)
+{
+       struct devlink *devlink = priv_to_devlink(mlxsw_sp->core);
+       u64 table_size;
+
+       table_size = MLXSW_CORE_RES_GET(mlxsw_sp->core, MAX_RIFS);
+       return devlink_dpipe_table_register(devlink,
+                                           MLXSW_SP_DPIPE_TABLE_NAME_ERIF,
+                                           &mlxsw_sp_erif_ops,
+                                           mlxsw_sp, table_size,
+                                           false);
+}
+
+static void mlxsw_sp_dpipe_erif_table_fini(struct mlxsw_sp *mlxsw_sp)
+{
+       struct devlink *devlink = priv_to_devlink(mlxsw_sp->core);
+
+       devlink_dpipe_table_unregister(devlink, MLXSW_SP_DPIPE_TABLE_NAME_ERIF);
+}
+
 int mlxsw_sp_dpipe_init(struct mlxsw_sp *mlxsw_sp)
 {
-       return devlink_dpipe_headers_register(priv_to_devlink(mlxsw_sp->core),
-                                             &mlxsw_sp_dpipe_headers);
+       struct devlink *devlink = priv_to_devlink(mlxsw_sp->core);
+       int err;
+
+       err = devlink_dpipe_headers_register(devlink,
+                                            &mlxsw_sp_dpipe_headers);
+       if (err)
+               return err;
+       err = mlxsw_sp_dpipe_erif_table_init(mlxsw_sp);
+       if (err)
+               goto err_erif_register;
+       return 0;
+
+err_erif_register:
+       devlink_dpipe_headers_unregister(priv_to_devlink(mlxsw_sp->core));
+       return err;
 }
 
 void mlxsw_sp_dpipe_fini(struct mlxsw_sp *mlxsw_sp)
 {
-       devlink_dpipe_headers_unregister(priv_to_devlink(mlxsw_sp->core));
+       struct devlink *devlink = priv_to_devlink(mlxsw_sp->core);
+
+       mlxsw_sp_dpipe_erif_table_fini(mlxsw_sp);
+       devlink_dpipe_headers_unregister(devlink);
 }
index ad16259..d208929 100644 (file)
@@ -38,4 +38,6 @@
 int mlxsw_sp_dpipe_init(struct mlxsw_sp *mlxsw_sp);
 void mlxsw_sp_dpipe_fini(struct mlxsw_sp *mlxsw_sp);
 
+#define MLXSW_SP_DPIPE_TABLE_NAME_ERIF "mlxsw_erif"
+
 #endif /* _MLXSW_PIPELINE_H_*/