ipsec: User can choose the UDP source port
[vpp.git] / src / vnet / ipsec / ipsec_sa.c
index f60566c..e5f01bf 100644 (file)
@@ -179,7 +179,7 @@ ipsec_sa_add_and_lock (u32 id,
                       u32 salt,
                       const ip46_address_t * tun_src,
                       const ip46_address_t * tun_dst, u32 * sa_out_index,
-                      u16 dst_port)
+                      u16 src_port, u16 dst_port)
 {
   vlib_main_t *vm = vlib_get_main ();
   ipsec_main_t *im = &ipsec_main;
@@ -329,15 +329,17 @@ ipsec_sa_add_and_lock (u32 id,
   if (ipsec_sa_is_set_UDP_ENCAP (sa))
     {
       if (dst_port == IPSEC_UDP_PORT_NONE)
-       {
-         sa->udp_hdr.src_port = clib_host_to_net_u16 (UDP_DST_PORT_ipsec);
-         sa->udp_hdr.dst_port = clib_host_to_net_u16 (UDP_DST_PORT_ipsec);
-       }
+       sa->udp_hdr.dst_port = clib_host_to_net_u16 (UDP_DST_PORT_ipsec);
       else
-       {
-         sa->udp_hdr.src_port = clib_host_to_net_u16 (dst_port);
-         sa->udp_hdr.dst_port = clib_host_to_net_u16 (dst_port);
-       }
+       sa->udp_hdr.dst_port = clib_host_to_net_u16 (dst_port);
+
+      if (src_port == IPSEC_UDP_PORT_NONE)
+       sa->udp_hdr.src_port = clib_host_to_net_u16 (UDP_DST_PORT_ipsec);
+      else
+       sa->udp_hdr.src_port = clib_host_to_net_u16 (src_port);
+
+      if (ipsec_sa_is_set_IS_INBOUND (sa))
+       ipsec_register_udp_port (clib_host_to_net_u16 (sa->udp_hdr.dst_port));
     }
 
   hash_set (im->sa_index_by_sa_id, sa->id, sa_index);
@@ -361,6 +363,9 @@ ipsec_sa_del (ipsec_sa_t * sa)
   /* no recovery possible when deleting an SA */
   (void) ipsec_call_add_del_callbacks (im, sa, sa_index, 0);
 
+  if (ipsec_sa_is_set_UDP_ENCAP (sa) && ipsec_sa_is_set_IS_INBOUND (sa))
+    ipsec_unregister_udp_port (clib_net_to_host_u16 (sa->udp_hdr.dst_port));
+
   if (ipsec_sa_is_set_IS_TUNNEL (sa) && !ipsec_sa_is_set_IS_INBOUND (sa))
     {
       fib_entry_untrack (sa->fib_entry_index, sa->sibling);