Allow UPDSA to change output_mark to permit policy separation of packet routing decisions from SA keying in systems that use mark-based routing.
In the output_mark, used as a routing and firewall mark for outbound packets, is made update-able which allows routing decisions to be handled independently of keying/SA creation. To maintain consistency with other optional attributes, the output mark is only updated if sent with a non-zero value. Once set, the output mark may not be reset to zero, which ensures that updating the SA does not require the mark to be re-sent to avoid the value being clobbered. The per-SA lock and the xfrm_state_lock are taken in that order to avoid a deadlock with xfrm_timer_handler(), which also takes the locks in that order. Signed-off-by: Nathan Harold <nhar...@google.com> Change-Id: Ia05c6733a94c1901cd1e54eb7c7e237704678d71 --- net/xfrm/xfrm_state.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c index f595797a20ce..5d6085e81030 100644 --- a/net/xfrm/xfrm_state.c +++ b/net/xfrm/xfrm_state.c @@ -1554,6 +1554,13 @@ int xfrm_state_update(struct xfrm_state *x) if (x1->curlft.use_time) xfrm_state_check_expire(x1); + spin_lock_bh(&net->xfrm.xfrm_state_lock); + if (x->props.output_mark) { + x1->props.output_mark = x->props.output_mark; + __xfrm_state_bump_genids(x1); + } + spin_unlock_bh(&net->xfrm.xfrm_state_lock); + err = 0; x->km.state = XFRM_STATE_DEAD; __xfrm_state_put(x); -- 2.17.0.441.gb46fe60e1d-goog