ipsec: Tunnel SA DSCP behaviour
[vpp.git] / src / vnet / ipsec / esp_encrypt.c
index f546168..ed49cdc 100644 (file)
@@ -24,6 +24,7 @@
 #include <vnet/ipsec/ipsec.h>
 #include <vnet/ipsec/ipsec_tun.h>
 #include <vnet/ipsec/esp.h>
+#include <vnet/tunnel/tunnel_dp.h>
 
 #define foreach_esp_encrypt_next                   \
 _(DROP4, "ip4-drop")                               \
@@ -743,9 +744,22 @@ esp_encrypt_inline (vlib_main_t * vm, vlib_node_runtime_t * node,
              u16 len = sizeof (ip6_header_t);
              hdr_len += len;
              ip6 = (ip6_header_t *) (payload - hdr_len);
-             clib_memcpy_fast (ip6, &sa0->ip6_hdr, len);
-             *next_hdr_ptr = (is_ip6 ?
-                              IP_PROTOCOL_IPV6 : IP_PROTOCOL_IP_IN_IP);
+             clib_memcpy_fast (ip6, &sa0->ip6_hdr, sizeof (ip6_header_t));
+
+             if (is_ip6)
+               {
+                 *next_hdr_ptr = IP_PROTOCOL_IPV6;
+                 tunnel_encap_fixup_6o6 (sa0->tunnel_flags,
+                                         (const ip6_header_t *) payload,
+                                         ip6);
+               }
+             else
+               {
+                 *next_hdr_ptr = IP_PROTOCOL_IP_IN_IP;
+                 tunnel_encap_fixup_4o6 (sa0->tunnel_flags,
+                                         (const ip4_header_t *) payload,
+                                         ip6);
+               }
              len = payload_len_total + hdr_len - len;
              ip6->payload_length = clib_net_to_host_u16 (len);
            }
@@ -755,9 +769,22 @@ esp_encrypt_inline (vlib_main_t * vm, vlib_node_runtime_t * node,
              u16 len = sizeof (ip4_header_t);
              hdr_len += len;
              ip4 = (ip4_header_t *) (payload - hdr_len);
-             clib_memcpy_fast (ip4, &sa0->ip4_hdr, len);
-             *next_hdr_ptr = (is_ip6 ?
-                              IP_PROTOCOL_IPV6 : IP_PROTOCOL_IP_IN_IP);
+             clib_memcpy_fast (ip4, &sa0->ip4_hdr, sizeof (ip4_header_t));
+
+             if (is_ip6)
+               {
+                 *next_hdr_ptr = IP_PROTOCOL_IPV6;
+                 tunnel_encap_fixup_6o4_w_chksum (sa0->tunnel_flags,
+                                                  (const ip6_header_t *)
+                                                  payload, ip4);
+               }
+             else
+               {
+                 *next_hdr_ptr = IP_PROTOCOL_IP_IN_IP;
+                 tunnel_encap_fixup_4o4_w_chksum (sa0->tunnel_flags,
+                                                  (const ip4_header_t *)
+                                                  payload, ip4);
+               }
              len = payload_len_total + hdr_len;
              esp_update_ip4_hdr (ip4, len, /* is_transport */ 0, 0);
            }