Skip to content

Commit c7d759e

Browse files
kuba-moodavem330
authored andcommitted
ethtool: add tunnel info interface
Add an interface to report offloaded UDP ports via ethtool netlink. Now that core takes care of tracking which UDP tunnel ports the NICs are aware of we can quite easily export this information out to user space. The responsibility of writing the netlink dumps is split between ethtool code and udp_tunnel_nic.c - since udp_tunnel module may not always be loaded, yet we should always report the capabilities of the NIC. $ ethtool --show-tunnels eth0 Tunnel information for eth0: UDP port table 0: Size: 4 Types: vxlan No entries UDP port table 1: Size: 4 Types: geneve, vxlan-gpe Entries (1): port 1230, vxlan-gpe v4: - back to v2, build fix is now directly in udp_tunnel.h v3: - don't compile ETHTOOL_MSG_TUNNEL_INFO_GET in if CONFIG_INET not set. v2: - fix string set count, - reorder enums in the uAPI, - fix type of ETHTOOL_A_TUNNEL_UDP_TABLE_TYPES to bitset in docs and comments. Signed-off-by: Jakub Kicinski <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent cc4e383 commit c7d759e

File tree

12 files changed

+472
-1
lines changed

12 files changed

+472
-1
lines changed

Documentation/networking/ethtool-netlink.rst

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1230,6 +1230,39 @@ used to report the amplitude of the reflection for a given pair.
12301230
| | | ``ETHTOOL_A_CABLE_AMPLITUDE_mV`` | s16 | Reflection amplitude |
12311231
+-+-+-----------------------------------------+--------+----------------------+
12321232

1233+
TUNNEL_INFO
1234+
===========
1235+
1236+
Gets information about the tunnel state NIC is aware of.
1237+
1238+
Request contents:
1239+
1240+
===================================== ====== ==========================
1241+
``ETHTOOL_A_TUNNEL_INFO_HEADER`` nested request header
1242+
===================================== ====== ==========================
1243+
1244+
Kernel response contents:
1245+
1246+
+---------------------------------------------+--------+---------------------+
1247+
| ``ETHTOOL_A_TUNNEL_INFO_HEADER`` | nested | reply header |
1248+
+---------------------------------------------+--------+---------------------+
1249+
| ``ETHTOOL_A_TUNNEL_INFO_UDP_PORTS`` | nested | all UDP port tables |
1250+
+-+-------------------------------------------+--------+---------------------+
1251+
| | ``ETHTOOL_A_TUNNEL_UDP_TABLE`` | nested | one UDP port table |
1252+
+-+-+-----------------------------------------+--------+---------------------+
1253+
| | | ``ETHTOOL_A_TUNNEL_UDP_TABLE_SIZE`` | u32 | max size of the |
1254+
| | | | | table |
1255+
+-+-+-----------------------------------------+--------+---------------------+
1256+
| | | ``ETHTOOL_A_TUNNEL_UDP_TABLE_TYPES`` | bitset | tunnel types which |
1257+
| | | | | table can hold |
1258+
+-+-+-----------------------------------------+--------+---------------------+
1259+
| | | ``ETHTOOL_A_TUNNEL_UDP_TABLE_ENTRY`` | nested | offloaded UDP port |
1260+
+-+-+-+---------------------------------------+--------+---------------------+
1261+
| | | | ``ETHTOOL_A_TUNNEL_UDP_ENTRY_PORT`` | be16 | UDP port |
1262+
+-+-+-+---------------------------------------+--------+---------------------+
1263+
| | | | ``ETHTOOL_A_TUNNEL_UDP_ENTRY_TYPE`` | u32 | tunnel type |
1264+
+-+-+-+---------------------------------------+--------+---------------------+
1265+
12331266
Request translation
12341267
===================
12351268

include/net/udp_tunnel.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,10 @@ struct udp_tunnel_nic_ops {
255255
void (*add_port)(struct net_device *dev, struct udp_tunnel_info *ti);
256256
void (*del_port)(struct net_device *dev, struct udp_tunnel_info *ti);
257257
void (*reset_ntf)(struct net_device *dev);
258+
259+
size_t (*dump_size)(struct net_device *dev, unsigned int table);
260+
int (*dump_write)(struct net_device *dev, unsigned int table,
261+
struct sk_buff *skb);
258262
};
259263

260264
#ifdef CONFIG_INET
@@ -318,4 +322,21 @@ static inline void udp_tunnel_nic_reset_ntf(struct net_device *dev)
318322
if (udp_tunnel_nic_ops)
319323
udp_tunnel_nic_ops->reset_ntf(dev);
320324
}
325+
326+
static inline size_t
327+
udp_tunnel_nic_dump_size(struct net_device *dev, unsigned int table)
328+
{
329+
if (!udp_tunnel_nic_ops)
330+
return 0;
331+
return udp_tunnel_nic_ops->dump_size(dev, table);
332+
}
333+
334+
static inline int
335+
udp_tunnel_nic_dump_write(struct net_device *dev, unsigned int table,
336+
struct sk_buff *skb)
337+
{
338+
if (!udp_tunnel_nic_ops)
339+
return 0;
340+
return udp_tunnel_nic_ops->dump_write(dev, table, skb);
341+
}
321342
#endif

include/uapi/linux/ethtool.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -669,6 +669,7 @@ enum ethtool_link_ext_substate_cable_issue {
669669
* @ETH_SS_SOF_TIMESTAMPING: SOF_TIMESTAMPING_* flags
670670
* @ETH_SS_TS_TX_TYPES: timestamping Tx types
671671
* @ETH_SS_TS_RX_FILTERS: timestamping Rx filters
672+
* @ETH_SS_UDP_TUNNEL_TYPES: UDP tunnel types
672673
*/
673674
enum ethtool_stringset {
674675
ETH_SS_TEST = 0,
@@ -686,6 +687,7 @@ enum ethtool_stringset {
686687
ETH_SS_SOF_TIMESTAMPING,
687688
ETH_SS_TS_TX_TYPES,
688689
ETH_SS_TS_RX_FILTERS,
690+
ETH_SS_UDP_TUNNEL_TYPES,
689691

690692
/* add new constants above here */
691693
ETH_SS_COUNT

include/uapi/linux/ethtool_netlink.h

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ enum {
4141
ETHTOOL_MSG_TSINFO_GET,
4242
ETHTOOL_MSG_CABLE_TEST_ACT,
4343
ETHTOOL_MSG_CABLE_TEST_TDR_ACT,
44+
ETHTOOL_MSG_TUNNEL_INFO_GET,
4445

4546
/* add new constants above here */
4647
__ETHTOOL_MSG_USER_CNT,
@@ -556,6 +557,60 @@ enum {
556557
ETHTOOL_A_CABLE_TEST_TDR_NTF_MAX = __ETHTOOL_A_CABLE_TEST_TDR_NTF_CNT - 1
557558
};
558559

560+
/* TUNNEL INFO */
561+
562+
enum {
563+
ETHTOOL_UDP_TUNNEL_TYPE_VXLAN,
564+
ETHTOOL_UDP_TUNNEL_TYPE_GENEVE,
565+
ETHTOOL_UDP_TUNNEL_TYPE_VXLAN_GPE,
566+
567+
__ETHTOOL_UDP_TUNNEL_TYPE_CNT
568+
};
569+
570+
enum {
571+
ETHTOOL_A_TUNNEL_UDP_ENTRY_UNSPEC,
572+
573+
ETHTOOL_A_TUNNEL_UDP_ENTRY_PORT, /* be16 */
574+
ETHTOOL_A_TUNNEL_UDP_ENTRY_TYPE, /* u32 */
575+
576+
/* add new constants above here */
577+
__ETHTOOL_A_TUNNEL_UDP_ENTRY_CNT,
578+
ETHTOOL_A_TUNNEL_UDP_ENTRY_MAX = (__ETHTOOL_A_TUNNEL_UDP_ENTRY_CNT - 1)
579+
};
580+
581+
enum {
582+
ETHTOOL_A_TUNNEL_UDP_TABLE_UNSPEC,
583+
584+
ETHTOOL_A_TUNNEL_UDP_TABLE_SIZE, /* u32 */
585+
ETHTOOL_A_TUNNEL_UDP_TABLE_TYPES, /* bitset */
586+
ETHTOOL_A_TUNNEL_UDP_TABLE_ENTRY, /* nest - _UDP_ENTRY_* */
587+
588+
/* add new constants above here */
589+
__ETHTOOL_A_TUNNEL_UDP_TABLE_CNT,
590+
ETHTOOL_A_TUNNEL_UDP_TABLE_MAX = (__ETHTOOL_A_TUNNEL_UDP_TABLE_CNT - 1)
591+
};
592+
593+
enum {
594+
ETHTOOL_A_TUNNEL_UDP_UNSPEC,
595+
596+
ETHTOOL_A_TUNNEL_UDP_TABLE, /* nest - _UDP_TABLE_* */
597+
598+
/* add new constants above here */
599+
__ETHTOOL_A_TUNNEL_UDP_CNT,
600+
ETHTOOL_A_TUNNEL_UDP_MAX = (__ETHTOOL_A_TUNNEL_UDP_CNT - 1)
601+
};
602+
603+
enum {
604+
ETHTOOL_A_TUNNEL_INFO_UNSPEC,
605+
ETHTOOL_A_TUNNEL_INFO_HEADER, /* nest - _A_HEADER_* */
606+
607+
ETHTOOL_A_TUNNEL_INFO_UDP_PORTS, /* nest - _UDP_TABLE */
608+
609+
/* add new constants above here */
610+
__ETHTOOL_A_TUNNEL_INFO_CNT,
611+
ETHTOOL_A_TUNNEL_INFO_MAX = (__ETHTOOL_A_TUNNEL_INFO_CNT - 1)
612+
};
613+
559614
/* generic netlink info */
560615
#define ETHTOOL_GENL_NAME "ethtool"
561616
#define ETHTOOL_GENL_VERSION 1

net/ethtool/Makefile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,5 @@ obj-$(CONFIG_ETHTOOL_NETLINK) += ethtool_nl.o
66

77
ethtool_nl-y := netlink.o bitset.o strset.o linkinfo.o linkmodes.o \
88
linkstate.o debug.o wol.o features.o privflags.o rings.o \
9-
channels.o coalesce.o pause.o eee.o tsinfo.o cabletest.o
9+
channels.o coalesce.o pause.o eee.o tsinfo.o cabletest.o \
10+
tunnels.o

net/ethtool/common.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
// SPDX-License-Identifier: GPL-2.0-only
22

3+
#include <linux/ethtool_netlink.h>
34
#include <linux/net_tstamp.h>
45
#include <linux/phy.h>
56
#include <linux/rtnetlink.h>
@@ -272,6 +273,14 @@ const char ts_rx_filter_names[][ETH_GSTRING_LEN] = {
272273
};
273274
static_assert(ARRAY_SIZE(ts_rx_filter_names) == __HWTSTAMP_FILTER_CNT);
274275

276+
const char udp_tunnel_type_names[][ETH_GSTRING_LEN] = {
277+
[ETHTOOL_UDP_TUNNEL_TYPE_VXLAN] = "vxlan",
278+
[ETHTOOL_UDP_TUNNEL_TYPE_GENEVE] = "geneve",
279+
[ETHTOOL_UDP_TUNNEL_TYPE_VXLAN_GPE] = "vxlan-gpe",
280+
};
281+
static_assert(ARRAY_SIZE(udp_tunnel_type_names) ==
282+
__ETHTOOL_UDP_TUNNEL_TYPE_CNT);
283+
275284
/* return false if legacy contained non-0 deprecated fields
276285
* maxtxpkt/maxrxpkt. rest of ksettings always updated
277286
*/

net/ethtool/common.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ extern const char wol_mode_names[][ETH_GSTRING_LEN];
2828
extern const char sof_timestamping_names[][ETH_GSTRING_LEN];
2929
extern const char ts_tx_type_names[][ETH_GSTRING_LEN];
3030
extern const char ts_rx_filter_names[][ETH_GSTRING_LEN];
31+
extern const char udp_tunnel_type_names[][ETH_GSTRING_LEN];
3132

3233
int __ethtool_get_link(struct net_device *dev);
3334

net/ethtool/netlink.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,12 @@ struct sk_buff *ethnl_reply_init(size_t payload, struct net_device *dev, u8 cmd,
181181
return NULL;
182182
}
183183

184+
void *ethnl_dump_put(struct sk_buff *skb, struct netlink_callback *cb, u8 cmd)
185+
{
186+
return genlmsg_put(skb, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq,
187+
&ethtool_genl_family, 0, cmd);
188+
}
189+
184190
void *ethnl_bcastmsg_put(struct sk_buff *skb, u8 cmd)
185191
{
186192
return genlmsg_put(skb, 0, ++ethnl_bcast_seq, &ethtool_genl_family, 0,
@@ -849,6 +855,12 @@ static const struct genl_ops ethtool_genl_ops[] = {
849855
.flags = GENL_UNS_ADMIN_PERM,
850856
.doit = ethnl_act_cable_test_tdr,
851857
},
858+
{
859+
.cmd = ETHTOOL_MSG_TUNNEL_INFO_GET,
860+
.doit = ethnl_tunnel_info_doit,
861+
.start = ethnl_tunnel_info_start,
862+
.dumpit = ethnl_tunnel_info_dumpit,
863+
},
852864
};
853865

854866
static const struct genl_multicast_group ethtool_nl_mcgrps[] = {

net/ethtool/netlink.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ int ethnl_fill_reply_header(struct sk_buff *skb, struct net_device *dev,
1919
struct sk_buff *ethnl_reply_init(size_t payload, struct net_device *dev, u8 cmd,
2020
u16 hdr_attrtype, struct genl_info *info,
2121
void **ehdrp);
22+
void *ethnl_dump_put(struct sk_buff *skb, struct netlink_callback *cb, u8 cmd);
2223
void *ethnl_bcastmsg_put(struct sk_buff *skb, u8 cmd);
2324
int ethnl_multicast(struct sk_buff *skb, struct net_device *dev);
2425

@@ -361,5 +362,8 @@ int ethnl_set_pause(struct sk_buff *skb, struct genl_info *info);
361362
int ethnl_set_eee(struct sk_buff *skb, struct genl_info *info);
362363
int ethnl_act_cable_test(struct sk_buff *skb, struct genl_info *info);
363364
int ethnl_act_cable_test_tdr(struct sk_buff *skb, struct genl_info *info);
365+
int ethnl_tunnel_info_doit(struct sk_buff *skb, struct genl_info *info);
366+
int ethnl_tunnel_info_start(struct netlink_callback *cb);
367+
int ethnl_tunnel_info_dumpit(struct sk_buff *skb, struct netlink_callback *cb);
364368

365369
#endif /* _NET_ETHTOOL_NETLINK_H */

net/ethtool/strset.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,11 @@ static const struct strset_info info_template[] = {
7575
.count = __HWTSTAMP_FILTER_CNT,
7676
.strings = ts_rx_filter_names,
7777
},
78+
[ETH_SS_UDP_TUNNEL_TYPES] = {
79+
.per_dev = false,
80+
.count = __ETHTOOL_UDP_TUNNEL_TYPE_CNT,
81+
.strings = udp_tunnel_type_names,
82+
},
7883
};
7984

8085
struct strset_req_info {

0 commit comments

Comments
 (0)