1) Number the routers (usually by assigning IP addresses). Router ID.
2) Assign the cost to each OSPF interface communicating with another router.
3) Multicast periodically a hello and establishes adjacency so routers will see who is on opposite side of its interface build Adjacency Table.
3) Router builds LinkStateDatabase by multicasting its own Adjacency Table and listening to others doing the same. The packets sending that information are called LinkStateAdvertisements.
4) At the end router sends Database Description (DBD) of its database to allow other routers to verify that databases are the same.
5) If the databases are the same then Run Dijkstra's builds Routing Information Base which is used to populate routing table (together with other protocols)
6) Then router gets to the state when periodically sends hello and Database Description
7) If discovered that databases are not the same then then ask for the Link State Update by sending Link State Request (for particular link)
8) Link State Acknowledgement to confirm that LSU was received.
9) Once databases are the same then run Dijkstra's again and build RIB and put routes into routing table.
10) Change of local link changes Adjacency tables and sends different DBDs what triggers LSUs
But, there are problems in the paradise:
1) Many routers on one interface -> DR/BDR ruters
2) Routing information comes from other sources (other Routing Protocols) -> LAS types
3) Network grows and OSPF becomes too intensive (traffic & CPU cycles) -> OSPF areas