+static_always_inline vnet_api_error_t
+ikev2_register_udp_port (ikev2_profile_t * p, u16 port)
+{
+ ikev2_main_t *km = &ikev2_main;
+ udp_dst_port_info_t *pi;
+
+ uword *v = hash_get (km->udp_ports, port);
+ pi = udp_get_dst_port_info (&udp_main, port, UDP_IP4);
+
+ if (v)
+ {
+ /* IKE already uses this port, only increment reference counter */
+ ASSERT (pi);
+ v[0]++;
+ }
+ else
+ {
+ if (pi)
+ return VNET_API_ERROR_UDP_PORT_TAKEN;
+
+ udp_register_dst_port (km->vlib_main, port,
+ ipsec4_tun_input_node.index, 1);
+ hash_set (km->udp_ports, port, 1);
+ }
+ p->dst_port = port;
+ return 0;
+}
+
+static_always_inline void
+ikev2_unregister_udp_port (ikev2_profile_t * p)
+{
+ ikev2_main_t *km = &ikev2_main;
+ uword *v;
+
+ if (p->dst_port == IPSEC_UDP_PORT_NONE)
+ return;
+
+ v = hash_get (km->udp_ports, p->dst_port);
+ if (!v)
+ return;
+
+ v[0]--;
+
+ if (v[0] == 0)
+ {
+ udp_unregister_dst_port (km->vlib_main, p->dst_port, 1);
+ hash_unset (km->udp_ports, p->dst_port);
+ }
+
+ p->dst_port = IPSEC_UDP_PORT_NONE;
+}
+