+/*
+ * Returns the index of the entry after the deleted one,
+ * or one past the last entry.
+ */
+static unsigned int
+efx_tunnel_config_udp_do_remove(
+ __in efx_tunnel_cfg_t *etcp,
+ __in unsigned int entry)
+{
+ EFSYS_ASSERT3U(etcp->etc_udp_entries_num, >, 0);
+ etcp->etc_udp_entries_num--;
+
+ if (entry < etcp->etc_udp_entries_num) {
+ memmove(&etcp->etc_udp_entries[entry],
+ &etcp->etc_udp_entries[entry + 1],
+ (etcp->etc_udp_entries_num - entry) *
+ sizeof (etcp->etc_udp_entries[0]));
+ }
+
+ memset(&etcp->etc_udp_entries[etcp->etc_udp_entries_num], 0,
+ sizeof (etcp->etc_udp_entries[0]));
+
+ return (entry);
+}
+
+/*
+ * Returns the index of the entry after the specified one,
+ * or one past the last entry. The index is correct whether
+ * the specified entry was removed or not.
+ */
+static unsigned int
+efx_tunnel_config_udp_remove_prepare(
+ __in efx_tunnel_cfg_t *etcp,
+ __in unsigned int entry)
+{
+ unsigned int next = entry + 1;
+
+ switch (etcp->etc_udp_entries[entry].etue_state) {
+ case EFX_TUNNEL_UDP_ENTRY_ADDED:
+ next = efx_tunnel_config_udp_do_remove(etcp, entry);
+ break;
+ case EFX_TUNNEL_UDP_ENTRY_REMOVED:
+ break;
+ case EFX_TUNNEL_UDP_ENTRY_APPLIED:
+ etcp->etc_udp_entries[entry].etue_state =
+ EFX_TUNNEL_UDP_ENTRY_REMOVED;
+ break;
+ default:
+ EFSYS_ASSERT(0);
+ break;
+ }
+
+ return (next);
+}
+