When loading data to PostGIS, there's no topology information associated with them. To create a useful topology the data needs to be “noded”. This means that where two or more roads form an intersection there it needs to be a node at the intersection and all the road segments need to be broken at the intersection, assuming that you can navigate from any of these segments to any other segment via that intersection. (Extract from pgrouting 2.0 documentation).
In your case, it seems that some nodes are common between bridges over roads and underneath roads. I don't know if those nodes were given in the ITN data or if you created them.
So you have to pass a clean network to pgrouting :
Let's say you have a bridge (A-B-C) and a road underneath (D-B-E) :
The table you pass to pgRouting is like :
source | target | geometry | cost
A | B | LINESTRING (A,B) | cost_ab
B | C | LINESTRING (B,C) | cost_bc
D | B | LINESTRING (D,B) | cost_db
B | E | LINESTRING (B,E) | cost_be
You have to modify it to
source |target | geometry | cost
A | C | LINESTRING (A,B,C) | cost_ab+cost_bc
D | E | LINESTRING (D,B,E) | cost_db+cost_be
You can create a temporary table and use some case statements to fill columns/filter your grade and generate the modified network.
Note that pgRouting 2.0 documentation gives an example (but with new methods) : pgRouting 2.0 Routing topology