diff options
author | Thomas Haller <thaller@redhat.com> | 2020-03-06 08:26:55 +0100 |
---|---|---|
committer | Thomas Haller <thaller@redhat.com> | 2020-03-06 09:52:27 +0100 |
commit | d482eec6b23ec7fe8735d84764637294c4f8d637 (patch) | |
tree | ba257e53f4c1d6bb2601c0a78a5c039ebe082afc | |
parent | a78b32a835cffb0eb01f77380d24fee7c33a4851 (diff) |
ifcfg-rh: use binary search for converting string to ethtool ID
Don't do a linear search through all names, but use binary search.
Upside: calling nms_ifcfg_rh_utils_get_ethtool_by_name() in a loop
(once over all 60 names) is 75% faster.
Downside: when adding a new feature, we have yet another line that we
need to add. Previously, adding a new feature required adding 7 lines,
not it is 8. But we didn't add a single feature since this was added,
so that happens very seldom.
Possible downside: is this code harder to read? Now we track both how to
convert the ID to name and back. This is redundant (and thus harder to
maintain). But it's really just one extra line per feature, for which there
is a unit test. So, when adding a new NMEthtoolID it would be pretty
hard to mess this up, because of all the tests and assertions.
So, maybe it's slightly harder to read. On the other hand, it unifies
handling for ethtool and kernel names, and the code has less logic
and is more descriptive. I don't think this is actually harder to maintain
and it should be easy to see that it is correct (readability).
-rw-r--r-- | src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.c | 118 |
1 files changed, 87 insertions, 31 deletions
diff --git a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.c b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.c index fb155365f2..1195d77d8d 100644 --- a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.c +++ b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.c @@ -579,31 +579,15 @@ const char *const _nm_ethtool_ifcfg_names[] = { ETHT_NAME (NM_ETHTOOL_ID_FEATURE_TX_VLAN_STAG_HW_INSERT, "tx-vlan-stag-hw-insert"), }; -const NMEthtoolData * -nms_ifcfg_rh_utils_get_ethtool_by_name (const char *name) -{ - static const struct { - NMEthtoolID ethtool_id; - const char *kernel_name; - } kernel_names[] = { - { NM_ETHTOOL_ID_FEATURE_GRO, "rx-gro" }, - { NM_ETHTOOL_ID_FEATURE_GSO, "tx-generic-segmentation" }, - { NM_ETHTOOL_ID_FEATURE_LRO, "rx-lro" }, - { NM_ETHTOOL_ID_FEATURE_NTUPLE, "rx-ntuple-filter" }, - { NM_ETHTOOL_ID_FEATURE_RX, "rx-checksum" }, - { NM_ETHTOOL_ID_FEATURE_RXHASH, "rx-hashing" }, - { NM_ETHTOOL_ID_FEATURE_RXVLAN, "rx-vlan-hw-parse" }, - { NM_ETHTOOL_ID_FEATURE_TXVLAN, "tx-vlan-hw-insert" }, - }; - guint i; - - for (i = 0; i < G_N_ELEMENTS (_nm_ethtool_ifcfg_names); i++) { - if (nm_streq (name, _nm_ethtool_ifcfg_names[i])) - return nm_ethtool_data[i]; - } - - /* Option not found. Note that ethtool utility has built-in features and - * NetworkManager's API follows the naming of these built-in features, whenever +static +NM_UTILS_STRING_TABLE_LOOKUP_DEFINE ( + _get_ethtoolid_by_name, + NMEthtoolID, + { nm_assert (name); }, + { return NM_ETHTOOL_ID_UNKNOWN; }, + + /* Map the names from kernel/ethtool/ifcfg to NMEthtoolID. Note that ethtool utility has built-in + * features and NetworkManager's API follows the naming of these built-in features, whenever * they exist. * For example, NM's "ethtool.feature-ntuple" corresponds to ethtool utility's "ntuple" * feature. However the underlying kernel feature is called "rx-ntuple-filter" (as reported @@ -611,13 +595,85 @@ nms_ifcfg_rh_utils_get_ethtool_by_name (const char *name) * * With ethtool utility, whose command line we attempt to parse here, the user can also * specify the name of the underlying kernel feature directly. So, check whether that is - * the case and if yes, map them to the corresponding NetworkManager's features. */ - for (i = 0; i < G_N_ELEMENTS (kernel_names); i++) { - if (nm_streq (name, kernel_names[i].kernel_name)) - return nm_ethtool_data[kernel_names[i].ethtool_id]; - } + * the case and if yes, map them to the corresponding NetworkManager's features. + * + * That is why there are duplicate IDs in this list. */ + { "esp-hw-offload", NM_ETHTOOL_ID_FEATURE_ESP_HW_OFFLOAD }, + { "esp-tx-csum-hw-offload", NM_ETHTOOL_ID_FEATURE_ESP_TX_CSUM_HW_OFFLOAD }, + { "fcoe-mtu", NM_ETHTOOL_ID_FEATURE_FCOE_MTU }, + { "gro", NM_ETHTOOL_ID_FEATURE_GRO }, + { "gso", NM_ETHTOOL_ID_FEATURE_GSO }, + { "highdma", NM_ETHTOOL_ID_FEATURE_HIGHDMA }, + { "hw-tc-offload", NM_ETHTOOL_ID_FEATURE_HW_TC_OFFLOAD }, + { "l2-fwd-offload", NM_ETHTOOL_ID_FEATURE_L2_FWD_OFFLOAD }, + { "loopback", NM_ETHTOOL_ID_FEATURE_LOOPBACK }, + { "lro", NM_ETHTOOL_ID_FEATURE_LRO }, + { "ntuple", NM_ETHTOOL_ID_FEATURE_NTUPLE }, + { "rx", NM_ETHTOOL_ID_FEATURE_RX }, + { "rx-all", NM_ETHTOOL_ID_FEATURE_RX_ALL }, + { "rx-checksum", NM_ETHTOOL_ID_FEATURE_RX }, // kernel-only name + { "rx-fcs", NM_ETHTOOL_ID_FEATURE_RX_FCS }, + { "rx-gro", NM_ETHTOOL_ID_FEATURE_GRO }, // kernel-only name + { "rx-gro-hw", NM_ETHTOOL_ID_FEATURE_RX_GRO_HW }, + { "rx-hashing", NM_ETHTOOL_ID_FEATURE_RXHASH }, // kernel-only name + { "rx-lro", NM_ETHTOOL_ID_FEATURE_LRO }, // kernel-only name + { "rx-ntuple-filter", NM_ETHTOOL_ID_FEATURE_NTUPLE }, // kernel-only name + { "rx-udp_tunnel-port-offload", NM_ETHTOOL_ID_FEATURE_RX_UDP_TUNNEL_PORT_OFFLOAD }, + { "rx-vlan-filter", NM_ETHTOOL_ID_FEATURE_RX_VLAN_FILTER }, + { "rx-vlan-hw-parse", NM_ETHTOOL_ID_FEATURE_RXVLAN }, // kernel-only name + { "rx-vlan-stag-filter", NM_ETHTOOL_ID_FEATURE_RX_VLAN_STAG_FILTER }, + { "rx-vlan-stag-hw-parse", NM_ETHTOOL_ID_FEATURE_RX_VLAN_STAG_HW_PARSE }, + { "rxhash", NM_ETHTOOL_ID_FEATURE_RXHASH }, + { "rxvlan", NM_ETHTOOL_ID_FEATURE_RXVLAN }, + { "sg", NM_ETHTOOL_ID_FEATURE_SG }, + { "tls-hw-record", NM_ETHTOOL_ID_FEATURE_TLS_HW_RECORD }, + { "tls-hw-tx-offload", NM_ETHTOOL_ID_FEATURE_TLS_HW_TX_OFFLOAD }, + { "tso", NM_ETHTOOL_ID_FEATURE_TSO }, + { "tx", NM_ETHTOOL_ID_FEATURE_TX }, + { "tx-checksum-fcoe-crc", NM_ETHTOOL_ID_FEATURE_TX_CHECKSUM_FCOE_CRC }, + { "tx-checksum-ip-generic", NM_ETHTOOL_ID_FEATURE_TX_CHECKSUM_IP_GENERIC }, + { "tx-checksum-ipv4", NM_ETHTOOL_ID_FEATURE_TX_CHECKSUM_IPV4 }, + { "tx-checksum-ipv6", NM_ETHTOOL_ID_FEATURE_TX_CHECKSUM_IPV6 }, + { "tx-checksum-sctp", NM_ETHTOOL_ID_FEATURE_TX_CHECKSUM_SCTP }, + { "tx-esp-segmentation", NM_ETHTOOL_ID_FEATURE_TX_ESP_SEGMENTATION }, + { "tx-fcoe-segmentation", NM_ETHTOOL_ID_FEATURE_TX_FCOE_SEGMENTATION }, + { "tx-generic-segmentation", NM_ETHTOOL_ID_FEATURE_GSO }, // kernel-only name + { "tx-gre-csum-segmentation", NM_ETHTOOL_ID_FEATURE_TX_GRE_CSUM_SEGMENTATION }, + { "tx-gre-segmentation", NM_ETHTOOL_ID_FEATURE_TX_GRE_SEGMENTATION }, + { "tx-gso-partial", NM_ETHTOOL_ID_FEATURE_TX_GSO_PARTIAL }, + { "tx-gso-robust", NM_ETHTOOL_ID_FEATURE_TX_GSO_ROBUST }, + { "tx-ipxip4-segmentation", NM_ETHTOOL_ID_FEATURE_TX_IPXIP4_SEGMENTATION }, + { "tx-ipxip6-segmentation", NM_ETHTOOL_ID_FEATURE_TX_IPXIP6_SEGMENTATION }, + { "tx-nocache-copy", NM_ETHTOOL_ID_FEATURE_TX_NOCACHE_COPY }, + { "tx-scatter-gather", NM_ETHTOOL_ID_FEATURE_TX_SCATTER_GATHER }, + { "tx-scatter-gather-fraglist", NM_ETHTOOL_ID_FEATURE_TX_SCATTER_GATHER_FRAGLIST }, + { "tx-sctp-segmentation", NM_ETHTOOL_ID_FEATURE_TX_SCTP_SEGMENTATION }, + { "tx-tcp-ecn-segmentation", NM_ETHTOOL_ID_FEATURE_TX_TCP_ECN_SEGMENTATION }, + { "tx-tcp-mangleid-segmentation", NM_ETHTOOL_ID_FEATURE_TX_TCP_MANGLEID_SEGMENTATION }, + { "tx-tcp-segmentation", NM_ETHTOOL_ID_FEATURE_TX_TCP_SEGMENTATION }, + { "tx-tcp6-segmentation", NM_ETHTOOL_ID_FEATURE_TX_TCP6_SEGMENTATION }, + { "tx-udp-segmentation", NM_ETHTOOL_ID_FEATURE_TX_UDP_SEGMENTATION }, + { "tx-udp_tnl-csum-segmentation", NM_ETHTOOL_ID_FEATURE_TX_UDP_TNL_CSUM_SEGMENTATION }, + { "tx-udp_tnl-segmentation", NM_ETHTOOL_ID_FEATURE_TX_UDP_TNL_SEGMENTATION }, + { "tx-vlan-hw-insert", NM_ETHTOOL_ID_FEATURE_TXVLAN }, // kernel-only name + { "tx-vlan-stag-hw-insert", NM_ETHTOOL_ID_FEATURE_TX_VLAN_STAG_HW_INSERT }, + { "txvlan", NM_ETHTOOL_ID_FEATURE_TXVLAN }, +); - return NULL; +const NMEthtoolData * +nms_ifcfg_rh_utils_get_ethtool_by_name (const char *name) +{ + NMEthtoolID id; + + id = _get_ethtoolid_by_name (name); + if (id == NM_ETHTOOL_ID_UNKNOWN) + return NULL; + + nm_assert (_NM_INT_NOT_NEGATIVE (id)); + nm_assert (id < G_N_ELEMENTS (nm_ethtool_data)); + nm_assert (nm_ethtool_data[id]); + nm_assert (nm_ethtool_data[id]->id == id); + return nm_ethtool_data[id]; } /*****************************************************************************/ |