VPP-363: add ability to change mac address of the interface
[vpp.git] / vnet / vnet / ipsec / ipsec_output.c
index 278dddc..ee21b77 100644 (file)
@@ -103,6 +103,9 @@ ipsec_output_policy_match (ipsec_spd_t * spd, u8 pr, u32 la, u32 ra, u16 lp,
   ipsec_policy_t *p;
   u32 *i;
 
+  if (!spd)
+    return 0;
+
   vec_foreach (i, spd->ipv4_outbound_policies)
   {
     p = pool_elt_at_index (spd->policies, *i);
@@ -159,6 +162,9 @@ ipsec_output_ip6_policy_match (ipsec_spd_t * spd,
   ipsec_policy_t *p;
   u32 *i;
 
+  if (!spd)
+    return 0;
+
   vec_foreach (i, spd->ipv6_outbound_policies)
   {
     p = pool_elt_at_index (spd->policies, *i);
@@ -219,14 +225,14 @@ ipsec_output_node_fn (vlib_main_t * vm,
       ip6_header_t *ip6_0 = 0;
       udp_header_t *udp0;
       u8 is_ipv6 = 0;
+      u32 iph_offset = 0;
 
       bi0 = from[0];
       b0 = vlib_get_buffer (vm, bi0);
       sw_if_index0 = vnet_buffer (b0)->sw_if_index[VLIB_TX];
-
-
-      ip0 = (ip4_header_t *) ((u8 *) vlib_buffer_get_current (b0) +
-                             sizeof (ethernet_header_t));
+      iph_offset = vnet_buffer (b0)->ip.save_rewrite_length;
+      ip0 = (ip4_header_t *) ((u8 *) vlib_buffer_get_current (b0)
+                             + iph_offset);
 
       /* just forward non ipv4 packets */
       if (PREDICT_FALSE ((ip0->ip_version_and_header_length & 0xF0) != 0x40))
@@ -236,8 +242,8 @@ ipsec_output_node_fn (vlib_main_t * vm,
              ((ip0->ip_version_and_header_length & 0xF0) == 0x60))
            {
              is_ipv6 = 1;
-             ip6_0 = (ip6_header_t *) ((u8 *) vlib_buffer_get_current (b0) +
-                                       sizeof (ethernet_header_t));
+             ip6_0 = (ip6_header_t *) ((u8 *) vlib_buffer_get_current (b0)
+                                       + iph_offset);
            }
          else
            {
@@ -271,10 +277,10 @@ ipsec_output_node_fn (vlib_main_t * vm,
          p0 = ipsec_output_ip6_policy_match (spd0,
                                              &ip6_0->src_address,
                                              &ip6_0->dst_address,
-                                             clib_net_to_host_u16 (udp0->
-                                                                   src_port),
-                                             clib_net_to_host_u16 (udp0->
-                                                                   dst_port),
+                                             clib_net_to_host_u16
+                                             (udp0->src_port),
+                                             clib_net_to_host_u16
+                                             (udp0->dst_port),
                                              ip6_0->protocol);
        }
       else
@@ -291,16 +297,14 @@ ipsec_output_node_fn (vlib_main_t * vm,
 #endif
 
          p0 = ipsec_output_policy_match (spd0, ip0->protocol,
-                                         clib_net_to_host_u32 (ip0->
-                                                               src_address.
-                                                               as_u32),
-                                         clib_net_to_host_u32 (ip0->
-                                                               dst_address.
-                                                               as_u32),
-                                         clib_net_to_host_u16 (udp0->
-                                                               src_port),
-                                         clib_net_to_host_u16 (udp0->
-                                                               dst_port));
+                                         clib_net_to_host_u32
+                                         (ip0->src_address.as_u32),
+                                         clib_net_to_host_u32
+                                         (ip0->dst_address.as_u32),
+                                         clib_net_to_host_u16
+                                         (udp0->src_port),
+                                         clib_net_to_host_u16
+                                         (udp0->dst_port));
        }
 
       if (PREDICT_TRUE (p0 != NULL))
@@ -311,7 +315,7 @@ ipsec_output_node_fn (vlib_main_t * vm,
              next_node_index = im->esp_encrypt_node_index;
              vnet_buffer (b0)->output_features.ipsec_sad_index =
                p0->sa_index;
-             vlib_buffer_advance (b0, sizeof (ethernet_header_t));
+             vlib_buffer_advance (b0, iph_offset);
              p0->counter.packets++;
              if (is_ipv6)
                {
@@ -367,7 +371,7 @@ ipsec_output_node_fn (vlib_main_t * vm,
       from += 1;
       n_left_from -= 1;
 
-      if (PREDICT_FALSE ((last_next_node_index != next_node_index)))
+      if (PREDICT_FALSE ((last_next_node_index != next_node_index) || f == 0))
        {
          /* if this is not 1st frame */
          if (f)