Make IPsec tunnel intf work with IPv4 output features 29/11629/2
authorMatthew Smith <mgsmith@netgate.com>
Mon, 9 Apr 2018 16:49:20 +0000 (11:49 -0500)
committerDamjan Marion <dmarion.lists@gmail.com>
Tue, 10 Apr 2018 10:30:11 +0000 (10:30 +0000)
With no IPv4 output features on an IPsec tunnel inferface,
when packets are forwarded to that interface, they reach
the ipsec-if-output node via the output_node_index on the
hw interface and they are handled correctly.

When an IPv4 output feature (e.g. output ACL, outbound
NAT) is enabled on an IPsec tunnel interface, outbound
IPsec stops working for that interface. The last node in
the ip4-output feature arc is interface-output. From there
a packet is sent to ipsec<N>-output, and then ipsec<N>-tx.
The tx function for an IPsec tunnel interface that is
called by ipsec<N>-tx is a dummy that doesn't do anything
except write a warning message.

Enable a feature on the interface-output feature arc for
an IPsec tunnel interface so the ipsec-if-output node is
reached from the interface-output node.

Change-Id: Ia9c73d3932f5930ec7ce0791a0375b1d37148b01
Signed-off-by: Matthew Smith <mgsmith@netgate.com>
src/vnet/interface_output.c
src/vnet/ipsec/ipsec_if.c

index 563f614..fe029b8 100644 (file)
@@ -1089,6 +1089,12 @@ VNET_FEATURE_INIT (span_tx, static) = {
   .runs_before = VNET_FEATURES ("interface-tx"),
 };
 
+VNET_FEATURE_INIT (ipsec_if_tx, static) = {
+  .arc_name = "interface-output",
+  .node_name = "ipsec-if-output",
+  .runs_before = VNET_FEATURES ("interface-tx"),
+};
+
 VNET_FEATURE_INIT (interface_tx, static) = {
   .arc_name = "interface-output",
   .node_name = "interface-tx",
index 0a08081..852b142 100644 (file)
@@ -242,6 +242,9 @@ ipsec_add_del_tunnel_if_internal (vnet_main_t * vnm,
       hi->output_node_index = ipsec_if_output_node.index;
       t->hw_if_index = hw_if_index;
 
+      vnet_feature_enable_disable ("interface-output", "ipsec-if-output",
+                                  hi->sw_if_index, 1, 0, 0);
+
       /*1st interface, register protocol */
       if (pool_elts (im->tunnel_interfaces) == 1)
        ip4_register_protocol (IP_PROTOCOL_IPSEC_ESP,
@@ -259,6 +262,10 @@ ipsec_add_del_tunnel_if_internal (vnet_main_t * vnm,
       t = pool_elt_at_index (im->tunnel_interfaces, p[0]);
       hi = vnet_get_hw_interface (vnm, t->hw_if_index);
       vnet_sw_interface_set_flags (vnm, hi->sw_if_index, 0);   /* admin down */
+
+      vnet_feature_enable_disable ("interface-output", "ipsec-if-output",
+                                  hi->sw_if_index, 0, 0, 0);
+
       vec_add1 (im->free_tunnel_if_indices, t->hw_if_index);
 
       vnet_interface_counter_lock (vim);