[patch net-next 0/8] mlxsw: Add IPv6 host dpipe table
STALE3337d
Revision v1 of 2 in this series.
17 messages,
4 authors,
2017-08-31 · open the first message on its own page
From: Jiri Pirko <redacted>
Arkadi says:
This patchset adds IPv6 host dpipe table support. This will provide the
ability to observe the hardware offloaded IPv6 neighbors.
Arkadi Sharshevsky (8):
devlink: Add IPv6 header for dpipe
mlxsw: spectrum_router: Export IPv6 link local address check helper
mlxsw: spectrum_dpipe: Add IPv6 host table initial support
mlxsw: spectrum_router: Add IPv6 neighbor access helper
mlxsw: spectrum_dpipe: Make host entry fill handler more generic
mlxsw: spectrum_dpipe: Add support for IPv6 host table dump
mlxsw: spectrum_router: Add support for setting counters on IPv6
neighbors
mlxsw: spectrum_dpipe: Add support for controlling IPv6 neighbor
counters
.../net/ethernet/mellanox/mlxsw/spectrum_dpipe.c | 182 ++++++++++++++++++---
.../net/ethernet/mellanox/mlxsw/spectrum_dpipe.h | 1 +
.../net/ethernet/mellanox/mlxsw/spectrum_router.c | 37 ++++-
.../net/ethernet/mellanox/mlxsw/spectrum_router.h | 3 +
include/net/devlink.h | 1 +
include/uapi/linux/devlink.h | 5 +
net/core/devlink.c | 17 ++
7 files changed, 219 insertions(+), 27 deletions(-)
--
2.9.3
From: Arkadi Sharshevsky <redacted>
This will be used by the IPv6 host table which will be introduced in the
following patches. The fields in the header are added per-use. This header
is global and can be reused by many drivers.
Signed-off-by: Arkadi Sharshevsky <redacted>
Signed-off-by: Jiri Pirko <redacted>
---
include/net/devlink.h | 1 +
include/uapi/linux/devlink.h | 5 +++++
net/core/devlink.c | 17 +++++++++++++++++
3 files changed, 23 insertions(+)
diff --git a/include/net/devlink.h b/include/net/devlink.h
index aaf7178..b9654e1 100644
--- a/include/net/devlink.h
+++ b/include/net/devlink.h @@ -330,6 +330,7 @@ int devlink_dpipe_match_put(struct sk_buff *skb,
struct devlink_dpipe_match * match );
extern struct devlink_dpipe_header devlink_dpipe_header_ethernet ;
extern struct devlink_dpipe_header devlink_dpipe_header_ipv4 ;
+ extern struct devlink_dpipe_header devlink_dpipe_header_ipv6 ;
#else
diff --git a/include/uapi/linux/devlink.h b/include/uapi/linux/devlink.h
index 6c17254..0cbca96 100644
--- a/include/uapi/linux/devlink.h
+++ b/include/uapi/linux/devlink.h @@ -234,9 +234,14 @@ enum devlink_dpipe_field_ipv4_id {
DEVLINK_DPIPE_FIELD_IPV4_DST_IP ,
};
+ enum devlink_dpipe_field_ipv6_id {
+ DEVLINK_DPIPE_FIELD_IPV6_DST_IP ,
+ };
+
enum devlink_dpipe_header_id {
DEVLINK_DPIPE_HEADER_ETHERNET ,
DEVLINK_DPIPE_HEADER_IPV4 ,
+ DEVLINK_DPIPE_HEADER_IPV6 ,
};
#endif /* _UAPI_LINUX_DEVLINK_H_ */ diff --git a/net/core/devlink.c b/net/core/devlink.c
index 194708a..47931a2 100644
--- a/net/core/devlink.c
+++ b/net/core/devlink.c @@ -63,6 +63,23 @@ struct devlink_dpipe_header devlink_dpipe_header_ipv4 = {
};
EXPORT_SYMBOL ( devlink_dpipe_header_ipv4 );
+ static struct devlink_dpipe_field devlink_dpipe_fields_ipv6 [] = {
+ {
+ . name = "destination ip" ,
+ . id = DEVLINK_DPIPE_FIELD_IPV6_DST_IP ,
+ . bitwidth = 128 ,
+ },
+ };
+
+ struct devlink_dpipe_header devlink_dpipe_header_ipv6 = {
+ . name = "ipv6" ,
+ . id = DEVLINK_DPIPE_HEADER_IPV6 ,
+ . fields = devlink_dpipe_fields_ipv6 ,
+ . fields_count = ARRAY_SIZE ( devlink_dpipe_fields_ipv6 ),
+ . global = true ,
+ };
+ EXPORT_SYMBOL ( devlink_dpipe_header_ipv6 );
+
EXPORT_TRACEPOINT_SYMBOL_GPL ( devlink_hwmsg );
static LIST_HEAD ( devlink_list ); --
2.9.3
From: Arkadi Sharshevsky <redacted>
Neighbors with link local addresses are not offloaded to the host table,
yet, the are maintained in the driver for adjacency table usage. When
dumping the IPv6 host neighbors this link local neighbors should be
ignored. This patch exports this helper for dpipe usage.
Signed-off-by: Arkadi Sharshevsky <redacted>
Signed-off-by: Jiri Pirko <redacted>
---
drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c | 6 ++++--
drivers/net/ethernet/mellanox/mlxsw/spectrum_router.h | 1 +
2 files changed, 5 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
index 377d85c..1f41bcd 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c @@ -1396,8 +1396,10 @@ mlxsw_sp_router_neigh_entry_op6(struct mlxsw_sp *mlxsw_sp,
mlxsw_reg_write ( mlxsw_sp -> core , MLXSW_REG ( rauht ), rauht_pl );
}
- static bool mlxsw_sp_neigh_ipv6_ignore ( struct neighbour * n )
+ bool mlxsw_sp_neigh_ipv6_ignore ( struct mlxsw_sp_neigh_entry * neigh_entry )
{
+ struct neighbour * n = neigh_entry -> key . n ;
+
/* Packets with a link-local destination address are trapped
* after LPM lookup and never reach the neighbour table , so
* there is no need to program such neighbours to the device . @@ -1420,7 +1422,7 @@ mlxsw_sp_neigh_entry_update(struct mlxsw_sp *mlxsw_sp,
mlxsw_sp_router_neigh_entry_op4 ( mlxsw_sp , neigh_entry ,
mlxsw_sp_rauht_op ( adding ));
} else if ( neigh_entry -> key . n -> tbl -> family == AF_INET6 ) {
- if ( mlxsw_sp_neigh_ipv6_ignore ( neigh_entry -> key . n ))
+ if ( mlxsw_sp_neigh_ipv6_ignore ( neigh_entry ))
return ;
mlxsw_sp_router_neigh_entry_op6 ( mlxsw_sp , neigh_entry ,
mlxsw_sp_rauht_op ( adding )); diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.h b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.h
index fb0f971..5b68616 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.h
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.h @@ -76,5 +76,6 @@ void
mlxsw_sp_neigh_entry_counter_update ( struct mlxsw_sp * mlxsw_sp ,
struct mlxsw_sp_neigh_entry * neigh_entry ,
bool adding );
+ bool mlxsw_sp_neigh_ipv6_ignore ( struct mlxsw_sp_neigh_entry * neigh_entry );
#endif /* _MLXSW_ROUTER_H_*/ --
2.9.3
From: Arkadi Sharshevsky <redacted>
Add IPv6 host table initial support. The action behavior for both IPv4/6
tables is the same, thus the same action dump op is used. Neighbors with
link local address are ignored.
Signed-off-by: Arkadi Sharshevsky <redacted>
Signed-off-by: Jiri Pirko <redacted>
---
.../net/ethernet/mellanox/mlxsw/spectrum_dpipe.c | 76 ++++++++++++++++++++--
.../net/ethernet/mellanox/mlxsw/spectrum_dpipe.h | 1 +
2 files changed, 71 insertions(+), 6 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_dpipe.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_dpipe.c
index 3ea1314..93ba6a6 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_dpipe.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_dpipe.c @@ -76,6 +76,7 @@ static struct devlink_dpipe_header *mlxsw_dpipe_headers[] = {
& mlxsw_sp_dpipe_header_metadata ,
& devlink_dpipe_header_ethernet ,
& devlink_dpipe_header_ipv4 ,
+ & devlink_dpipe_header_ipv6 ,
};
static struct devlink_dpipe_headers mlxsw_sp_dpipe_headers = { @@ -328,9 +329,21 @@ static int mlxsw_sp_dpipe_table_host_matches_dump(struct sk_buff *skb, int type)
if ( err )
return err ;
- match . type = DEVLINK_DPIPE_MATCH_TYPE_FIELD_EXACT ;
- match . header = & devlink_dpipe_header_ipv4 ;
- match . field_id = DEVLINK_DPIPE_FIELD_IPV4_DST_IP ;
+ switch ( type ) {
+ case AF_INET :
+ match . type = DEVLINK_DPIPE_MATCH_TYPE_FIELD_EXACT ;
+ match . header = & devlink_dpipe_header_ipv4 ;
+ match . field_id = DEVLINK_DPIPE_FIELD_IPV4_DST_IP ;
+ break ;
+ case AF_INET6 :
+ match . type = DEVLINK_DPIPE_MATCH_TYPE_FIELD_EXACT ;
+ match . header = & devlink_dpipe_header_ipv6 ;
+ match . field_id = DEVLINK_DPIPE_FIELD_IPV6_DST_IP ;
+ break ;
+ default :
+ WARN_ON ( 1 );
+ return - EINVAL ;
+ }
return devlink_dpipe_match_put ( skb , & match );
} @@ -342,7 +355,7 @@ mlxsw_sp_dpipe_table_host4_matches_dump(void *priv, struct sk_buff *skb)
}
static int
- mlxsw_sp_dpipe_table_host4_actions_dump ( void * priv , struct sk_buff * skb )
+ mlxsw_sp_dpipe_table_host_actions_dump ( void * priv , struct sk_buff * skb )
{
struct devlink_dpipe_action action = { 0 };
@@ -648,8 +661,15 @@ mlxsw_sp_dpipe_table_host_size_get(struct mlxsw_sp *mlxsw_sp, int type)
if ( ! rif )
continue ;
mlxsw_sp_rif_neigh_for_each ( neigh_entry , rif ) {
- if ( mlxsw_sp_neigh_entry_type ( neigh_entry ) != type )
+ int neigh_type = mlxsw_sp_neigh_entry_type ( neigh_entry );
+
+ if ( neigh_type != type )
continue ;
+
+ if ( neigh_type == AF_INET6 &&
+ mlxsw_sp_neigh_ipv6_ignore ( neigh_entry ))
+ continue ;
+
size ++ ;
}
} @@ -667,7 +687,7 @@ static u64 mlxsw_sp_dpipe_table_host4_size_get(void *priv)
static struct devlink_dpipe_table_ops mlxsw_sp_host4_ops = {
. matches_dump = mlxsw_sp_dpipe_table_host4_matches_dump ,
- . actions_dump = mlxsw_sp_dpipe_table_host4_actions_dump ,
+ . actions_dump = mlxsw_sp_dpipe_table_host_actions_dump ,
. entries_dump = mlxsw_sp_dpipe_table_host4_entries_dump ,
. counters_set_update = mlxsw_sp_dpipe_table_host4_counters_update ,
. size_get = mlxsw_sp_dpipe_table_host4_size_get , @@ -691,6 +711,43 @@ static void mlxsw_sp_dpipe_host4_table_fini(struct mlxsw_sp *mlxsw_sp)
MLXSW_SP_DPIPE_TABLE_NAME_HOST4 );
}
+ static int
+ mlxsw_sp_dpipe_table_host6_matches_dump ( void * priv , struct sk_buff * skb )
+ {
+ return mlxsw_sp_dpipe_table_host_matches_dump ( skb , AF_INET6 );
+ }
+
+ static u64 mlxsw_sp_dpipe_table_host6_size_get ( void * priv )
+ {
+ struct mlxsw_sp * mlxsw_sp = priv ;
+
+ return mlxsw_sp_dpipe_table_host_size_get ( mlxsw_sp , AF_INET6 );
+ }
+
+ static struct devlink_dpipe_table_ops mlxsw_sp_host6_ops = {
+ . matches_dump = mlxsw_sp_dpipe_table_host6_matches_dump ,
+ . actions_dump = mlxsw_sp_dpipe_table_host_actions_dump ,
+ . size_get = mlxsw_sp_dpipe_table_host6_size_get ,
+ };
+
+ static int mlxsw_sp_dpipe_host6_table_init ( struct mlxsw_sp * mlxsw_sp )
+ {
+ struct devlink * devlink = priv_to_devlink ( mlxsw_sp -> core );
+
+ return devlink_dpipe_table_register ( devlink ,
+ MLXSW_SP_DPIPE_TABLE_NAME_HOST6 ,
+ & mlxsw_sp_host6_ops ,
+ mlxsw_sp , false );
+ }
+
+ static void mlxsw_sp_dpipe_host6_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_HOST6 );
+ }
+
int mlxsw_sp_dpipe_init ( struct mlxsw_sp * mlxsw_sp )
{
struct devlink * devlink = priv_to_devlink ( mlxsw_sp -> core ); @@ -707,8 +764,14 @@ int mlxsw_sp_dpipe_init(struct mlxsw_sp *mlxsw_sp)
err = mlxsw_sp_dpipe_host4_table_init ( mlxsw_sp );
if ( err )
goto err_host4_table_init ;
+
+ err = mlxsw_sp_dpipe_host6_table_init ( mlxsw_sp );
+ if ( err )
+ goto err_host6_table_init ;
return 0 ;
+ err_host6_table_init :
+ mlxsw_sp_dpipe_host4_table_fini ( mlxsw_sp );
err_host4_table_init :
mlxsw_sp_dpipe_erif_table_fini ( mlxsw_sp );
err_erif_table_init : @@ -720,6 +783,7 @@ void mlxsw_sp_dpipe_fini(struct mlxsw_sp *mlxsw_sp)
{
struct devlink * devlink = priv_to_devlink ( mlxsw_sp -> core );
+ mlxsw_sp_dpipe_host6_table_fini ( mlxsw_sp );
mlxsw_sp_dpipe_host4_table_fini ( mlxsw_sp );
mlxsw_sp_dpipe_erif_table_fini ( mlxsw_sp );
devlink_dpipe_headers_unregister ( devlink ); diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_dpipe.h b/drivers/net/ethernet/mellanox/mlxsw/spectrum_dpipe.h
index c56a3d9..283fde4 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_dpipe.h
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_dpipe.h @@ -55,5 +55,6 @@ static inline void mlxsw_sp_dpipe_fini(struct mlxsw_sp *mlxsw_sp)
#define MLXSW_SP_DPIPE_TABLE_NAME_ERIF "mlxsw_erif"
#define MLXSW_SP_DPIPE_TABLE_NAME_HOST4 "mlxsw_host4"
+ #define MLXSW_SP_DPIPE_TABLE_NAME_HOST6 "mlxsw_host6"
#endif /* _MLXSW_PIPELINE_H_*/ --
2.9.3
From: Arkadi Sharshevsky <redacted>
Add helper for accessing destination IP in case of IPv6 neighbor.
Signed-off-by: Arkadi Sharshevsky <redacted>
Signed-off-by: Jiri Pirko <redacted>
---
drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c | 9 +++++++++
drivers/net/ethernet/mellanox/mlxsw/spectrum_router.h | 2 ++
2 files changed, 11 insertions(+)
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
index 1f41bcd..db57c0c 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c @@ -947,6 +947,15 @@ u32 mlxsw_sp_neigh4_entry_dip(struct mlxsw_sp_neigh_entry *neigh_entry)
return ntohl ( * (( __be32 * ) n -> primary_key ));
}
+ struct in6_addr *
+ mlxsw_sp_neigh6_entry_dip ( struct mlxsw_sp_neigh_entry * neigh_entry )
+ {
+ struct neighbour * n ;
+
+ n = neigh_entry -> key . n ;
+ return ( struct in6_addr * ) & n -> primary_key ;
+ }
+
int mlxsw_sp_neigh_counter_get ( struct mlxsw_sp * mlxsw_sp ,
struct mlxsw_sp_neigh_entry * neigh_entry ,
u64 * p_counter ) diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.h b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.h
index 5b68616..87a04af 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.h
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.h @@ -65,6 +65,8 @@ int mlxsw_sp_neigh_entry_type(struct mlxsw_sp_neigh_entry *neigh_entry);
unsigned char *
mlxsw_sp_neigh_entry_ha ( struct mlxsw_sp_neigh_entry * neigh_entry );
u32 mlxsw_sp_neigh4_entry_dip ( struct mlxsw_sp_neigh_entry * neigh_entry );
+ struct in6_addr *
+ mlxsw_sp_neigh6_entry_dip ( struct mlxsw_sp_neigh_entry * neigh_entry );
#define mlxsw_sp_rif_neigh_for_each(neigh_entry, rif) \
for ( neigh_entry = mlxsw_sp_rif_neigh_next ( rif , NULL ); neigh_entry ; \ --
2.9.3
From: Arkadi Sharshevsky <redacted>
Change the host entry filler helper to be applicable for both IPv4/6
addresses.
Signed-off-by: Arkadi Sharshevsky <redacted>
Signed-off-by: Jiri Pirko <redacted>
---
drivers/net/ethernet/mellanox/mlxsw/spectrum_dpipe.c | 13 +++++--------
1 file changed, 5 insertions(+), 8 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_dpipe.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_dpipe.c
index 93ba6a6..5924e97 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_dpipe.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_dpipe.c @@ -439,13 +439,12 @@ mlxsw_sp_dpipe_table_host_entry_prepare(struct devlink_dpipe_entry *entry,
}
static void
- __mlxsw_sp_dpipe_table_host4_entry_fill ( struct devlink_dpipe_entry * entry ,
- struct mlxsw_sp_rif * rif ,
- unsigned char * ha , u32 dip )
+ __mlxsw_sp_dpipe_table_host_entry_fill ( struct devlink_dpipe_entry * entry ,
+ struct mlxsw_sp_rif * rif ,
+ unsigned char * ha , void * dip )
{
struct devlink_dpipe_value * value ;
u32 * rif_value ;
- u32 * dip_value ;
u8 * ha_value ;
/* Set Match RIF index */ @@ -458,9 +457,7 @@ __mlxsw_sp_dpipe_table_host4_entry_fill(struct devlink_dpipe_entry *entry,
/* Set Match DIP */
value = & entry -> match_values [ MLXSW_SP_DPIPE_TABLE_HOST_MATCH_DIP ];
-
- dip_value = value -> value ;
- * dip_value = dip ;
+ memcpy ( value -> value , dip , value -> value_size );
/* Set Action DMAC */
value = entry -> action_values ; @@ -478,7 +475,7 @@ mlxsw_sp_dpipe_table_host4_entry_fill(struct devlink_dpipe_entry *entry,
ha = mlxsw_sp_neigh_entry_ha ( neigh_entry );
dip = mlxsw_sp_neigh4_entry_dip ( neigh_entry );
- __mlxsw_sp_dpipe_table_host4_entry_fill ( entry , rif , ha , dip );
+ __mlxsw_sp_dpipe_table_host_entry_fill ( entry , rif , ha , & dip );
}
static void --
2.9.3
From: Arkadi Sharshevsky <redacted>
Add support for IPv6 host table dump.
Signed-off-by: Arkadi Sharshevsky <redacted>
Signed-off-by: Jiri Pirko <redacted>
---
.../net/ethernet/mellanox/mlxsw/spectrum_dpipe.c | 75 ++++++++++++++++++++--
1 file changed, 70 insertions(+), 5 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_dpipe.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_dpipe.c
index 5924e97..75da2ef 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_dpipe.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_dpipe.c @@ -386,8 +386,19 @@ mlxsw_sp_dpipe_table_host_match_action_prepare(struct devlink_dpipe_match *match
match = & matches [ MLXSW_SP_DPIPE_TABLE_HOST_MATCH_DIP ];
match -> type = DEVLINK_DPIPE_MATCH_TYPE_FIELD_EXACT ;
- match -> header = & devlink_dpipe_header_ipv4 ;
- match -> field_id = DEVLINK_DPIPE_FIELD_IPV4_DST_IP ;
+ switch ( type ) {
+ case AF_INET :
+ match -> header = & devlink_dpipe_header_ipv4 ;
+ match -> field_id = DEVLINK_DPIPE_FIELD_IPV4_DST_IP ;
+ break ;
+ case AF_INET6 :
+ match -> header = & devlink_dpipe_header_ipv6 ;
+ match -> field_id = DEVLINK_DPIPE_FIELD_IPV6_DST_IP ;
+ break ;
+ default :
+ WARN_ON ( 1 );
+ return ;
+ }
action -> type = DEVLINK_DPIPE_ACTION_TYPE_FIELD_MODIFY ;
action -> header = & devlink_dpipe_header_ethernet ; @@ -424,7 +435,18 @@ mlxsw_sp_dpipe_table_host_entry_prepare(struct devlink_dpipe_entry *entry,
match_value = & match_values [ MLXSW_SP_DPIPE_TABLE_HOST_MATCH_DIP ];
match_value -> match = match ;
- match_value -> value_size = sizeof ( u32 );
+ switch ( type ) {
+ case AF_INET :
+ match_value -> value_size = sizeof ( u32 );
+ break ;
+ case AF_INET6 :
+ match_value -> value_size = sizeof ( struct in6_addr );
+ break ;
+ default :
+ WARN_ON ( 1 );
+ return - EINVAL ;
+ }
+
match_value -> value = kmalloc ( match_value -> value_size , GFP_KERNEL );
if ( ! match_value -> value )
return - ENOMEM ; @@ -479,6 +501,20 @@ mlxsw_sp_dpipe_table_host4_entry_fill(struct devlink_dpipe_entry *entry,
}
static void
+ mlxsw_sp_dpipe_table_host6_entry_fill ( struct devlink_dpipe_entry * entry ,
+ struct mlxsw_sp_neigh_entry * neigh_entry ,
+ struct mlxsw_sp_rif * rif )
+ {
+ struct in6_addr * dip ;
+ unsigned char * ha ;
+
+ ha = mlxsw_sp_neigh_entry_ha ( neigh_entry );
+ dip = mlxsw_sp_neigh6_entry_dip ( neigh_entry );
+
+ __mlxsw_sp_dpipe_table_host_entry_fill ( entry , rif , ha , dip );
+ }
+
+ static void
mlxsw_sp_dpipe_table_host_entry_fill ( struct mlxsw_sp * mlxsw_sp ,
struct devlink_dpipe_entry * entry ,
struct mlxsw_sp_neigh_entry * neigh_entry , @@ -487,7 +523,18 @@ mlxsw_sp_dpipe_table_host_entry_fill(struct mlxsw_sp *mlxsw_sp,
{
int err ;
- mlxsw_sp_dpipe_table_host4_entry_fill ( entry , neigh_entry , rif );
+ switch ( type ) {
+ case AF_INET :
+ mlxsw_sp_dpipe_table_host4_entry_fill ( entry , neigh_entry , rif );
+ break ;
+ case AF_INET6 :
+ mlxsw_sp_dpipe_table_host6_entry_fill ( entry , neigh_entry , rif );
+ break ;
+ default :
+ WARN_ON ( 1 );
+ return ;
+ }
+
err = mlxsw_sp_neigh_counter_get ( mlxsw_sp , neigh_entry ,
& entry -> counter );
if ( ! err ) @@ -526,7 +573,13 @@ mlxsw_sp_dpipe_table_host_entries_get(struct mlxsw_sp *mlxsw_sp,
rif_neigh_count = 0 ;
mlxsw_sp_rif_neigh_for_each ( neigh_entry , rif ) {
- if ( mlxsw_sp_neigh_entry_type ( neigh_entry ) != type )
+ int neigh_type = mlxsw_sp_neigh_entry_type ( neigh_entry );
+
+ if ( neigh_type != type )
+ continue ;
+
+ if ( neigh_type == AF_INET6 &&
+ mlxsw_sp_neigh_ipv6_ignore ( neigh_entry ))
continue ;
if ( rif_neigh_count < rif_neigh_skip ) @@ -714,6 +767,17 @@ mlxsw_sp_dpipe_table_host6_matches_dump(void *priv, struct sk_buff *skb)
return mlxsw_sp_dpipe_table_host_matches_dump ( skb , AF_INET6 );
}
+ static int
+ mlxsw_sp_dpipe_table_host6_entries_dump ( void * priv , bool counters_enabled ,
+ struct devlink_dpipe_dump_ctx * dump_ctx )
+ {
+ struct mlxsw_sp * mlxsw_sp = priv ;
+
+ return mlxsw_sp_dpipe_table_host_entries_dump ( mlxsw_sp ,
+ counters_enabled ,
+ dump_ctx , AF_INET6 );
+ }
+
static u64 mlxsw_sp_dpipe_table_host6_size_get ( void * priv )
{
struct mlxsw_sp * mlxsw_sp = priv ; @@ -724,6 +788,7 @@ static u64 mlxsw_sp_dpipe_table_host6_size_get(void *priv)
static struct devlink_dpipe_table_ops mlxsw_sp_host6_ops = {
. matches_dump = mlxsw_sp_dpipe_table_host6_matches_dump ,
. actions_dump = mlxsw_sp_dpipe_table_host_actions_dump ,
+ . entries_dump = mlxsw_sp_dpipe_table_host6_entries_dump ,
. size_get = mlxsw_sp_dpipe_table_host6_size_get ,
};
--
2.9.3
From: Arkadi Sharshevsky <redacted>
Add support for setting counters on IPv6 neighbors based on dpipe's host6
table counter status.
Signed-off-by: Arkadi Sharshevsky <redacted>
Signed-off-by: Jiri Pirko <redacted>
---
.../net/ethernet/mellanox/mlxsw/spectrum_router.c | 22 +++++++++++++++++-----
1 file changed, 17 insertions(+), 5 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
index db57c0c..0cf6810 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c @@ -1008,21 +1008,33 @@ mlxsw_sp_neigh_entry_remove(struct mlxsw_sp *mlxsw_sp,
}
static bool
- mlxsw_sp_neigh4_counter_should_alloc ( struct mlxsw_sp * mlxsw_sp )
+ mlxsw_sp_neigh_counter_should_alloc ( struct mlxsw_sp * mlxsw_sp ,
+ struct mlxsw_sp_neigh_entry * neigh_entry )
{
struct devlink * devlink ;
+ const char * table_name ;
+
+ switch ( mlxsw_sp_neigh_entry_type ( neigh_entry )) {
+ case AF_INET :
+ table_name = MLXSW_SP_DPIPE_TABLE_NAME_HOST4 ;
+ break ;
+ case AF_INET6 :
+ table_name = MLXSW_SP_DPIPE_TABLE_NAME_HOST6 ;
+ break ;
+ default :
+ WARN_ON ( 1 );
+ return false ;
+ }
devlink = priv_to_devlink ( mlxsw_sp -> core );
- return devlink_dpipe_table_counter_enabled ( devlink ,
- MLXSW_SP_DPIPE_TABLE_NAME_HOST4 );
+ return devlink_dpipe_table_counter_enabled ( devlink , table_name );
}
static void
mlxsw_sp_neigh_counter_alloc ( struct mlxsw_sp * mlxsw_sp ,
struct mlxsw_sp_neigh_entry * neigh_entry )
{
- if ( mlxsw_sp_neigh_entry_type ( neigh_entry ) != AF_INET ||
- ! mlxsw_sp_neigh4_counter_should_alloc ( mlxsw_sp ))
+ if ( ! mlxsw_sp_neigh_counter_should_alloc ( mlxsw_sp , neigh_entry ))
return ;
if ( mlxsw_sp_flow_counter_alloc ( mlxsw_sp , & neigh_entry -> counter_index )) --
2.9.3
From: Arkadi Sharshevsky <redacted>
Add support for controlling IPv6 neighbor counters via dpipe.
Signed-off-by: Arkadi Sharshevsky <redacted>
Signed-off-by: Jiri Pirko <redacted>
---
drivers/net/ethernet/mellanox/mlxsw/spectrum_dpipe.c | 18 +++++++++++++++++-
1 file changed, 17 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_dpipe.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_dpipe.c
index 75da2ef..51e6846 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_dpipe.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_dpipe.c @@ -679,8 +679,15 @@ mlxsw_sp_dpipe_table_host_counters_update(struct mlxsw_sp *mlxsw_sp,
if ( ! rif )
continue ;
mlxsw_sp_rif_neigh_for_each ( neigh_entry , rif ) {
- if ( mlxsw_sp_neigh_entry_type ( neigh_entry ) != type )
+ int neigh_type = mlxsw_sp_neigh_entry_type ( neigh_entry );
+
+ if ( neigh_type != type )
+ continue ;
+
+ if ( neigh_type == AF_INET6 &&
+ mlxsw_sp_neigh_ipv6_ignore ( neigh_entry ))
continue ;
+
mlxsw_sp_neigh_entry_counter_update ( mlxsw_sp ,
neigh_entry ,
enable ); @@ -778,6 +785,14 @@ mlxsw_sp_dpipe_table_host6_entries_dump(void *priv, bool counters_enabled,
dump_ctx , AF_INET6 );
}
+ static int mlxsw_sp_dpipe_table_host6_counters_update ( void * priv , bool enable )
+ {
+ struct mlxsw_sp * mlxsw_sp = priv ;
+
+ mlxsw_sp_dpipe_table_host_counters_update ( mlxsw_sp , enable , AF_INET6 );
+ return 0 ;
+ }
+
static u64 mlxsw_sp_dpipe_table_host6_size_get ( void * priv )
{
struct mlxsw_sp * mlxsw_sp = priv ; @@ -789,6 +804,7 @@ static struct devlink_dpipe_table_ops mlxsw_sp_host6_ops = {
. matches_dump = mlxsw_sp_dpipe_table_host6_matches_dump ,
. actions_dump = mlxsw_sp_dpipe_table_host_actions_dump ,
. entries_dump = mlxsw_sp_dpipe_table_host6_entries_dump ,
+ . counters_set_update = mlxsw_sp_dpipe_table_host6_counters_update ,
. size_get = mlxsw_sp_dpipe_table_host6_size_get ,
};
--
2.9.3
On Wed, Aug 30, 2017 at 02:02:58PM +0200, Jiri Pirko wrote: From: Jiri Pirko <redacted>
Arkadi says:
This patchset adds IPv6 host dpipe table support. This will provide the
ability to observe the hardware offloaded IPv6 neighbors.
Hi Jiri, Arkadi
Could you give us an example of the output seen in user space.
Thanks
Andrew
On 8/30/17 11:26 AM, Andrew Lunn wrote: On Wed, Aug 30, 2017 at 02:02:58PM +0200, Jiri Pirko wrote: quoted From: Jiri Pirko <redacted>
Arkadi says:
This patchset adds IPv6 host dpipe table support. This will provide the
ability to observe the hardware offloaded IPv6 neighbors.
Hi Jiri, Arkadi
Could you give us an example of the output seen in user space.
Thanks
Andrew
Posting iproute2 patches with the set would be helpful as well.
On 8/30/17 6:03 AM, Jiri Pirko wrote: quoted hunk @@ -328,9 +329,21 @@ static int mlxsw_sp_dpipe_table_host_matches_dump(struct sk_buff *skb, int type)
if (err)
return err;
- match.type = DEVLINK_DPIPE_MATCH_TYPE_FIELD_EXACT;
- match.header = &devlink_dpipe_header_ipv4;
- match.field_id = DEVLINK_DPIPE_FIELD_IPV4_DST_IP;
+ switch (type) {
+ case AF_INET:
+ match.type = DEVLINK_DPIPE_MATCH_TYPE_FIELD_EXACT;
+ match.header = &devlink_dpipe_header_ipv4;
+ match.field_id = DEVLINK_DPIPE_FIELD_IPV4_DST_IP;
+ break;
+ case AF_INET6:
+ match.type = DEVLINK_DPIPE_MATCH_TYPE_FIELD_EXACT;
+ match.header = &devlink_dpipe_header_ipv6;
+ match.field_id = DEVLINK_DPIPE_FIELD_IPV6_DST_IP;
+ break;
+ default:
+ WARN_ON(1);
Why a warn for dump request of an unsupported family?
quoted hunk + return -EINVAL;
+ }
return devlink_dpipe_match_put(skb, &match);
} @@ -342,7 +355,7 @@ mlxsw_sp_dpipe_table_host4_matches_dump(void *priv, struct sk_buff *skb)
On 8/30/17 6:03 AM, Jiri Pirko wrote: quoted hunk diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_dpipe.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_dpipe.c
index 5924e97..75da2ef 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_dpipe.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_dpipe.c @@ -386,8 +386,19 @@ mlxsw_sp_dpipe_table_host_match_action_prepare(struct devlink_dpipe_match *match
match = & matches [ MLXSW_SP_DPIPE_TABLE_HOST_MATCH_DIP ];
match -> type = DEVLINK_DPIPE_MATCH_TYPE_FIELD_EXACT ;
- match -> header = & devlink_dpipe_header_ipv4 ;
- match -> field_id = DEVLINK_DPIPE_FIELD_IPV4_DST_IP ;
+ switch ( type ) {
+ case AF_INET :
+ match -> header = & devlink_dpipe_header_ipv4 ;
+ match -> field_id = DEVLINK_DPIPE_FIELD_IPV4_DST_IP ;
+ break ;
+ case AF_INET6 :
+ match -> header = & devlink_dpipe_header_ipv6 ;
+ match -> field_id = DEVLINK_DPIPE_FIELD_IPV6_DST_IP ;
+ break ;
+ default :
+ WARN_ON ( 1 );
Here as well.
quoted hunk + return;
+ }
action->type = DEVLINK_DPIPE_ACTION_TYPE_FIELD_MODIFY;
action->header = &devlink_dpipe_header_ethernet; @@ -424,7 +435,18 @@ mlxsw_sp_dpipe_table_host_entry_prepare(struct devlink_dpipe_entry *entry,
match_value = &match_values[MLXSW_SP_DPIPE_TABLE_HOST_MATCH_DIP];
match_value->match = match;
- match_value->value_size = sizeof(u32);
+ switch (type) {
+ case AF_INET:
+ match_value->value_size = sizeof(u32);
+ break;
+ case AF_INET6:
+ match_value->value_size = sizeof(struct in6_addr);
+ break;
+ default:
+ WARN_ON(1);
And here. WARN_ON is overkill
quoted hunk + return -EINVAL;
+ }
+
match_value->value = kmalloc(match_value->value_size, GFP_KERNEL);
if (!match_value->value)
return -ENOMEM;
On 8/30/17 6:03 AM, Jiri Pirko wrote: quoted hunk diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
index db57c0c..0cf6810 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c @@ -1008,21 +1008,33 @@ mlxsw_sp_neigh_entry_remove(struct mlxsw_sp *mlxsw_sp,
}
static bool
- mlxsw_sp_neigh4_counter_should_alloc ( struct mlxsw_sp * mlxsw_sp )
+ mlxsw_sp_neigh_counter_should_alloc ( struct mlxsw_sp * mlxsw_sp ,
+ struct mlxsw_sp_neigh_entry * neigh_entry )
{
struct devlink * devlink ;
+ const char * table_name ;
+
+ switch ( mlxsw_sp_neigh_entry_type ( neigh_entry )) {
+ case AF_INET :
+ table_name = MLXSW_SP_DPIPE_TABLE_NAME_HOST4 ;
+ break ;
+ case AF_INET6 :
+ table_name = MLXSW_SP_DPIPE_TABLE_NAME_HOST6 ;
+ break ;
+ default :
+ WARN_ON ( 1 );
Another unnecessary WARN_ON
quoted hunk + return false;
+ }
devlink = priv_to_devlink(mlxsw_sp->core);
- return devlink_dpipe_table_counter_enabled(devlink,
- MLXSW_SP_DPIPE_TABLE_NAME_HOST4);
+ return devlink_dpipe_table_counter_enabled(devlink, table_name);
}
Wed, Aug 30, 2017 at 07:36:13PM CEST, dsahern@gmail.com wrote: On 8/30/17 6:03 AM, Jiri Pirko wrote: quoted @@ -328,9 +329,21 @@ static int mlxsw_sp_dpipe_table_host_matches_dump(struct sk_buff *skb, int type)
if (err)
return err;
- match.type = DEVLINK_DPIPE_MATCH_TYPE_FIELD_EXACT;
- match.header = &devlink_dpipe_header_ipv4;
- match.field_id = DEVLINK_DPIPE_FIELD_IPV4_DST_IP;
+ switch (type) {
+ case AF_INET:
+ match.type = DEVLINK_DPIPE_MATCH_TYPE_FIELD_EXACT;
+ match.header = &devlink_dpipe_header_ipv4;
+ match.field_id = DEVLINK_DPIPE_FIELD_IPV4_DST_IP;
+ break;
+ case AF_INET6:
+ match.type = DEVLINK_DPIPE_MATCH_TYPE_FIELD_EXACT;
+ match.header = &devlink_dpipe_header_ipv6;
+ match.field_id = DEVLINK_DPIPE_FIELD_IPV6_DST_IP;
+ break;
+ default:
+ WARN_ON(1);
Why a warn for dump request of an unsupported family?
It's a handling of default case that should not happen unless there is a
bug in kernel.
quoted + return -EINVAL;
+ }
return devlink_dpipe_match_put(skb, &match);
} @@ -342,7 +355,7 @@ mlxsw_sp_dpipe_table_host4_matches_dump(void *priv, struct sk_buff *skb)
Wed, Aug 30, 2017 at 07:42:36PM CEST, dsahern@gmail.com wrote: On 8/30/17 6:03 AM, Jiri Pirko wrote: quoted diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_dpipe.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_dpipe.c
index 5924e97..75da2ef 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_dpipe.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_dpipe.c @@ -386,8 +386,19 @@ mlxsw_sp_dpipe_table_host_match_action_prepare(struct devlink_dpipe_match *match
match = & matches [ MLXSW_SP_DPIPE_TABLE_HOST_MATCH_DIP ];
match -> type = DEVLINK_DPIPE_MATCH_TYPE_FIELD_EXACT ;
- match -> header = & devlink_dpipe_header_ipv4 ;
- match -> field_id = DEVLINK_DPIPE_FIELD_IPV4_DST_IP ;
+ switch ( type ) {
+ case AF_INET :
+ match -> header = & devlink_dpipe_header_ipv4 ;
+ match -> field_id = DEVLINK_DPIPE_FIELD_IPV4_DST_IP ;
+ break ;
+ case AF_INET6 :
+ match -> header = & devlink_dpipe_header_ipv6 ;
+ match -> field_id = DEVLINK_DPIPE_FIELD_IPV6_DST_IP ;
+ break ;
+ default :
+ WARN_ON ( 1 );
Here as well.
quoted + return;
+ }
action->type = DEVLINK_DPIPE_ACTION_TYPE_FIELD_MODIFY;
action->header = &devlink_dpipe_header_ethernet; @@ -424,7 +435,18 @@ mlxsw_sp_dpipe_table_host_entry_prepare(struct devlink_dpipe_entry *entry,
match_value = &match_values[MLXSW_SP_DPIPE_TABLE_HOST_MATCH_DIP];
match_value->match = match;
- match_value->value_size = sizeof(u32);
+ switch (type) {
+ case AF_INET:
+ match_value->value_size = sizeof(u32);
+ break;
+ case AF_INET6:
+ match_value->value_size = sizeof(struct in6_addr);
+ break;
+ default:
+ WARN_ON(1);
And here. WARN_ON is overkill
Again, only in case of bug in kernel.
quoted + return -EINVAL;
+ }
+
match_value->value = kmalloc(match_value->value_size, GFP_KERNEL);
if (!match_value->value)
return -ENOMEM;
On 08/30/2017 08:26 PM, Andrew Lunn wrote: On Wed, Aug 30, 2017 at 02:02:58PM +0200, Jiri Pirko wrote: quoted From: Jiri Pirko <redacted>
Arkadi says:
This patchset adds IPv6 host dpipe table support. This will provide the
ability to observe the hardware offloaded IPv6 neighbors.
Hi Jiri, Arkadi
Could you give us an example of the output seen in user space.
Thanks
Andrew
Yeah Sure,
Andrew, please note that the output can be done in JSON format with -j
-p flags so you always can expose multiple tables, and in user space
easily present the data as 2D array as you wish. This is just formatting
This is example for IPV4/6 host (neighbor) tables with two entries. The
table is an hash table which performs match on rif and dst_ip, then sets
the dst mac. The rif is an internal object which is mapped to ifindex.
This is an example for the IPv4:
$devlink dpipe table dump pci/0000:03:00.0 name mlxsw_host4
pci/0000:03:00.0:
index 0
match_value:
type field_exact header mlxsw_meta field erif_port mapping ifindex
mapping_value 732 value 0
type field_exact header ipv4 field destination ip value 20.0.0.1
action_value:
type field_modify header ethernet field destination_mac value
e4:1d:2d:a5:f0:4a
index 1
match_value:
type field_exact header mlxsw_meta field erif_port mapping ifindex
mapping_value 733 value 1
type field_exact header ipv4 field destination ip value 10.0.0.1
action_value:
type field_modify header ethernet field destination_mac value
e4:1d:2d:a5:f1:7e
This is an example for IPv6:
$devlink dpipe table dump pci/0000:03:00.0 name mlxsw_host6
pci/0000:03:00.0:
index 0
match_value:
type field_exact header mlxsw_meta field erif_port mapping ifindex
mapping_value 732 value 0
type field_exact header ipv6 field destination ip value
2001:2011:0:f101::2
action_value:
type field_modify header ethernet field destination_mac value
e4:1d:2d:a5:f0:4a
index 1
match_value:
type field_exact header mlxsw_meta field erif_port mapping ifindex
mapping_value 733 value 1
type field_exact header ipv6 field destination ip value
2001:1011:0:f101::2
action_value:
type field_modify header ethernet field destination_mac value
e4:1d:2d:a5:f1:7e
Thanks,
Arkadi