ipsec: fix tunnel protection removal
[vpp.git] / src / vnet / ipsec / ipsec_tun.c
index 46980df..7864cba 100644 (file)
@@ -39,38 +39,29 @@ static int
 ipsec_tun_protect_feature_set (ipsec_tun_protect_t * itp, u8 enable)
 {
   u32 sai = itp->itp_out_sa;
-  int is_ip4, is_l2, rv;
+  int rv;
 
-  is_ip4 = ip46_address_is_ip4 (&itp->itp_tun.src);
-  is_l2 = itp->itp_flags & IPSEC_PROTECT_L2;
+  const char *enc_node = (ip46_address_is_ip4 (&itp->itp_tun.src) ?
+                         "esp4-encrypt-tun" : "esp6-encrypt-tun");
 
-  if (is_ip4)
+  if (itp->itp_flags & IPSEC_PROTECT_L2)
     {
-      if (is_l2)
-       rv = vnet_feature_enable_disable ("ethernet-output",
-                                         "esp4-encrypt-tun",
-                                         itp->itp_sw_if_index, enable,
-                                         &sai, sizeof (sai));
-      else
-       rv = vnet_feature_enable_disable ("ip4-output",
-                                         "esp4-encrypt-tun",
-                                         itp->itp_sw_if_index, enable,
-                                         &sai, sizeof (sai));
+      rv = vnet_feature_enable_disable ("ethernet-output",
+                                       enc_node,
+                                       itp->itp_sw_if_index, enable,
+                                       &sai, sizeof (sai));
     }
   else
     {
-      if (is_l2)
-       rv = vnet_feature_enable_disable ("ethernet-output",
-                                         "esp6-encrypt-tun",
-                                         itp->itp_sw_if_index, enable,
-                                         &sai, sizeof (sai));
-      else
-       rv = vnet_feature_enable_disable ("ip6-output",
-                                         "esp6-encrypt-tun",
-                                         itp->itp_sw_if_index, enable,
-                                         &sai, sizeof (sai));
+      rv = vnet_feature_enable_disable ("ip4-output",
+                                       enc_node,
+                                       itp->itp_sw_if_index, enable,
+                                       &sai, sizeof (sai));
+      rv = vnet_feature_enable_disable ("ip6-output",
+                                       enc_node,
+                                       itp->itp_sw_if_index, enable,
+                                       &sai, sizeof (sai));
     }
-
   ASSERT (!rv);
   return (rv);
 }
@@ -98,10 +89,14 @@ ipsec_tun_protect_db_add (ipsec_main_t * im, const ipsec_tun_protect_t * itp)
       if (ip46_address_is_ip4 (&itp->itp_crypto.dst))
         {
           ipsec4_tunnel_key_t key = {
-            .remote_ip = itp->itp_crypto.dst.ip4.as_u32,
+            .remote_ip = itp->itp_crypto.dst.ip4,
             .spi = clib_host_to_net_u32 (sa->spi),
           };
           hash_set (im->tun4_protect_by_key, key.as_u64, res.as_u64);
+          if (1 == hash_elts(im->tun4_protect_by_key))
+            udp_register_dst_port (vlib_get_main(),
+                                   UDP_DST_PORT_ipsec,
+                                   ipsec4_tun_input_node.index, 1);
         }
       else
         {
@@ -127,10 +122,14 @@ ipsec_tun_protect_db_remove (ipsec_main_t * im,
       if (ip46_address_is_ip4 (&itp->itp_crypto.dst))
         {
           ipsec4_tunnel_key_t key = {
-            .remote_ip = itp->itp_crypto.dst.ip4.as_u32,
+            .remote_ip = itp->itp_crypto.dst.ip4,
             .spi = clib_host_to_net_u32 (sa->spi),
           };
-          hash_unset (im->tun4_protect_by_key, &key);
+          hash_unset (im->tun4_protect_by_key, key.as_u64);
+          if (0 == hash_elts(im->tun4_protect_by_key))
+            udp_unregister_dst_port (vlib_get_main(),
+                                     UDP_DST_PORT_ipsec,
+                                     1);
         }
       else
         {
@@ -359,10 +358,10 @@ ipsec_tun_protect_del (u32 sw_if_index)
 
   pool_put (ipsec_protect_pool, itp);
 
-  /* if (0 == hash_elts (im->tun4_protect_by_key)) */
-  /*   ip4_unregister_protocol (IP_PROTOCOL_IPSEC_ESP); */
-  /* if (0 == hash_elts (im->tun6_protect_by_key)) */
-  /*   ip6_unregister_protocol (IP_PROTOCOL_IPSEC_ESP); */
+  if (0 == hash_elts (im->tun4_protect_by_key))
+    ip4_unregister_protocol (IP_PROTOCOL_IPSEC_ESP);
+  if (0 == hash_elts (im->tun6_protect_by_key))
+    ip6_unregister_protocol (IP_PROTOCOL_IPSEC_ESP);
 
   return (0);
 }