-#define _(N, j, n, unused) \
- case SNAT_PROTOCOL_##N: \
- if (a->fib_index == rx_fib_index) \
- { \
- u16 port = snat_random_port (1, port_per_thread); \
- u16 attempts = port_per_thread; \
- while (attempts > 0) \
- { \
- --attempts; \
- portnum = port_thread_offset + port; \
- make_ed_kv (&a->addr, &r_addr, proto, s->out2in.fib_index, \
- clib_host_to_net_u16 (portnum), r_port, \
- s - tsm->sessions, out2in_ed_kv); \
- int rv = clib_bihash_add_del_16_8 (&tsm->out2in_ed, out2in_ed_kv, \
- 2 /* is_add */); \
- if (0 == rv) \
- { \
- ++a->busy_##n##_port_refcounts[portnum]; \
- a->busy_##n##_ports_per_thread[thread_index]++; \
- a->busy_##n##_ports++; \
- *allocated_addr = a->addr; \
- *allocated_port = clib_host_to_net_u16 (portnum); \
- return 0; \
- } \
- port = (port + 1) % port_per_thread; \
- } \
- } \
- else if (a->fib_index == ~0) \
- { \
- ga = a; \
- } \
+#define _(N, j, n, unused) \
+ case NAT_PROTOCOL_##N: \
+ if (a->fib_index == rx_fib_index) \
+ { \
+ /* first try port suggested by caller */ \
+ u16 port = clib_net_to_host_u16 (*outside_port); \
+ u16 port_offset = port - port_thread_offset; \
+ if (port <= port_thread_offset || \
+ port > port_thread_offset + port_per_thread) \
+ { \
+ /* need to pick a different port, suggested port doesn't fit in \
+ * this thread's port range */ \
+ port_offset = snat_random_port (0, port_per_thread - 1); \
+ port = port_thread_offset + port_offset; \
+ } \
+ u16 attempts = ED_PORT_ALLOC_ATTEMPTS; \
+ do \
+ { \
+ init_ed_kv (out2in_ed_kv, a->addr, clib_host_to_net_u16 (port), \
+ r_addr, r_port, s->out2in.fib_index, proto, \
+ thread_index, s - tsm->sessions); \
+ int rv = clib_bihash_add_del_16_8 (&sm->out2in_ed, out2in_ed_kv, \
+ 2 /* is_add */); \
+ if (0 == rv) \
+ { \
+ ++a->busy_##n##_port_refcounts[port]; \
+ a->busy_##n##_ports_per_thread[thread_index]++; \
+ a->busy_##n##_ports++; \
+ *outside_addr = a->addr; \
+ *outside_port = clib_host_to_net_u16 (port); \
+ return 0; \
+ } \
+ port_offset = snat_random_port (0, port_per_thread - 1); \
+ port = port_thread_offset + port_offset; \
+ --attempts; \
+ } \
+ while (attempts > 0); \
+ } \
+ else if (a->fib_index == ~0) \
+ { \
+ ga = a; \
+ } \