summaryrefslogtreecommitdiffstats
path: root/src/vnet/ip
diff options
context:
space:
mode:
authorFlorin Coras <fcoras@cisco.com>2017-10-02 00:18:51 -0700
committerDave Barach <openvpp@barachs.net>2017-10-10 20:42:50 +0000
commitcea194d8f973a2f2b5ef72d212533057174cc70a (patch)
tree6fdd2e8a929c62625d1ad35bfbec342129989aef /src/vnet/ip
parent1f36a93d3d68f5ba6dcda08809394ce757cefd72 (diff)
session: add support for application namespacing
Applications are now provided the option to select the namespace they are to be attached to and the scope of their attachement. Application namespaces are meant to: 1) constrain the scope of communication through the network by association with source interfaces and/or fib tables that provide the source ips to be used and limit the scope of routing 2) provide a namespace local scope to session layer communication, as opposed to the global scope provided by 1). That is, sessions can be established without assistance from transport and network layers. Albeit, zero/local-host ip addresses must still be provided in session establishment messages due to existing application idiosyncrasies. This mode of communication uses shared-memory fifos (cut-through sessions) exclusively. If applications request no namespace, they are assigned to the default one, which at its turn uses the default fib. Applications can request access to both local and global scopes for a namespace. If no scope is specified, session layer defaults to the global one. When a sw_if_index is provided for a namespace, zero-ip (INADDR_ANY) binds are converted to binds to the requested interface. Change-Id: Ia0f660bbf7eec7f89673f75b4821fc7c3d58e3d1 Signed-off-by: Florin Coras <fcoras@cisco.com>
Diffstat (limited to 'src/vnet/ip')
-rw-r--r--src/vnet/ip/ip.c124
-rw-r--r--src/vnet/ip/ip.h7
-rwxr-xr-xsrc/vnet/ip/ip4_forward.c5
-rw-r--r--src/vnet/ip/ip6_forward.c26
4 files changed, 162 insertions, 0 deletions
diff --git a/src/vnet/ip/ip.c b/src/vnet/ip/ip.c
new file mode 100644
index 00000000000..caa553dd6d7
--- /dev/null
+++ b/src/vnet/ip/ip.c
@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) 2017 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <vnet/ip/ip.h>
+#include <vnet/fib/fib_table.h>
+
+u8
+ip_is_zero (ip46_address_t * ip46_address, u8 is_ip4)
+{
+ if (is_ip4)
+ return (ip46_address->ip4.as_u32 == 0);
+ else
+ return (ip46_address->as_u64[0] == 0 && ip46_address->as_u64[1] == 0);
+}
+
+u8
+ip_is_local_host (ip46_address_t * ip46_address, u8 is_ip4)
+{
+ if (is_ip4)
+ return (ip46_address->ip4.as_u8[0] == 127);
+ else
+ return (ip46_address->as_u64[0] == 0 && ip46_address->as_u64[1] == 1);
+}
+
+/**
+ * Checks that an ip is local to the requested fib
+ */
+u8
+ip_is_local (u32 fib_index, ip46_address_t * ip46_address, u8 is_ip4)
+{
+ fib_node_index_t fei;
+ fib_entry_flag_t flags;
+ fib_prefix_t prefix;
+
+ /* Check if requester is local */
+ if (is_ip4)
+ {
+ prefix.fp_len = 32;
+ prefix.fp_proto = FIB_PROTOCOL_IP4;
+ }
+ else
+ {
+ prefix.fp_len = 128;
+ prefix.fp_proto = FIB_PROTOCOL_IP6;
+ }
+
+ clib_memcpy (&prefix.fp_addr, ip46_address, sizeof (ip46_address_t));
+ fei = fib_table_lookup (0, &prefix);
+ flags = fib_entry_get_flags (fei);
+
+ return (flags & FIB_ENTRY_FLAG_LOCAL);
+}
+
+u8
+ip_interface_has_address (u32 sw_if_index, ip46_address_t * ip, u8 is_ip4)
+{
+ ip_interface_address_t *ia = 0;
+
+ if (is_ip4)
+ {
+ ip_lookup_main_t *lm4 = &ip4_main.lookup_main;
+ ip4_address_t *ip4;
+ /* *INDENT-OFF* */
+ foreach_ip_interface_address (lm4, ia, sw_if_index, 1 /* unnumbered */ ,
+ ({
+ ip4 = ip_interface_address_get_address (lm4, ia);
+ if (ip4_address_compare (ip4, &ip->ip4) == 0)
+ return 1;
+ }));
+ /* *INDENT-ON* */
+ }
+ else
+ {
+ ip_lookup_main_t *lm6 = &ip6_main.lookup_main;
+ ip6_address_t *ip6;
+ /* *INDENT-OFF* */
+ foreach_ip_interface_address (lm6, ia, sw_if_index, 1 /* unnumbered */ ,
+ ({
+ ip6 = ip_interface_address_get_address (lm6, ia);
+ if (ip6_address_compare (ip6, &ip->ip6) == 0)
+ return 1;
+ }));
+ /* *INDENT-ON* */
+ }
+ return 0;
+}
+
+void
+ip_copy (ip46_address_t * dst, ip46_address_t * src, u8 is_ip4)
+{
+ if (is_ip4)
+ dst->ip4.as_u32 = src->ip4.as_u32;
+ else
+ clib_memcpy (&dst->ip6, &src->ip6, sizeof (ip6_address_t));
+}
+
+void
+ip_set (ip46_address_t * dst, void *src, u8 is_ip4)
+{
+ if (is_ip4)
+ dst->ip4.as_u32 = ((ip4_address_t *) src)->as_u32;
+ else
+ clib_memcpy (&dst->ip6, (ip6_address_t *) src, sizeof (ip6_address_t));
+}
+
+/*
+ * fd.io coding-style-patch-verification: ON
+ *
+ * Local Variables:
+ * eval: (c-set-style "gnu")
+ * End:
+ */
diff --git a/src/vnet/ip/ip.h b/src/vnet/ip/ip.h
index 7e26bc6c135..3b3a465d042 100644
--- a/src/vnet/ip/ip.h
+++ b/src/vnet/ip/ip.h
@@ -192,6 +192,13 @@ void ip_table_delete (fib_protocol_t fproto, u32 table_id, u8 is_api);
int ip_table_bind (fib_protocol_t fproto, u32 sw_if_index,
u32 table_id, u8 is_api);
+u8 ip_is_zero (ip46_address_t * ip46_address, u8 is_ip4);
+u8 ip_is_local_host (ip46_address_t * ip46_address, u8 is_ip4);
+u8 ip_is_local (u32 fib_index, ip46_address_t * ip46_address, u8 is_ip4);
+u8 ip_interface_has_address (u32 sw_if_index, ip46_address_t * ip, u8 is_ip4);
+void ip_copy (ip46_address_t * dst, ip46_address_t * src, u8 is_ip4);
+void ip_set (ip46_address_t * dst, void *src, u8 is_ip4);
+
#endif /* included_ip_main_h */
/*
diff --git a/src/vnet/ip/ip4_forward.c b/src/vnet/ip/ip4_forward.c
index daffae410cc..c2a2f79e02f 100755
--- a/src/vnet/ip/ip4_forward.c
+++ b/src/vnet/ip/ip4_forward.c
@@ -1606,6 +1606,10 @@ ip4_local_inline (vlib_main_t * vm,
(vnet_buffer (p1)->sw_if_index[VLIB_TX] ==
(u32) ~ 0) ? fib_index1 : vnet_buffer (p1)->sw_if_index[VLIB_TX];
+ /* TODO maybe move to lookup? */
+ vnet_buffer (p0)->ip.fib_index = fib_index0;
+ vnet_buffer (p1)->ip.fib_index = fib_index1;
+
mtrie0 = &ip4_fib_get (fib_index0)->mtrie;
mtrie1 = &ip4_fib_get (fib_index1)->mtrie;
@@ -1744,6 +1748,7 @@ ip4_local_inline (vlib_main_t * vm,
fib_index0 =
(vnet_buffer (p0)->sw_if_index[VLIB_TX] ==
(u32) ~ 0) ? fib_index0 : vnet_buffer (p0)->sw_if_index[VLIB_TX];
+ vnet_buffer (p0)->ip.fib_index = fib_index0;
mtrie0 = &ip4_fib_get (fib_index0)->mtrie;
leaf0 = ip4_fib_mtrie_lookup_step_one (mtrie0, &ip0->src_address);
leaf0 = ip4_fib_mtrie_lookup_step (mtrie0, leaf0, &ip0->src_address,
diff --git a/src/vnet/ip/ip6_forward.c b/src/vnet/ip/ip6_forward.c
index f54b433485f..6b89ec38aae 100644
--- a/src/vnet/ip/ip6_forward.c
+++ b/src/vnet/ip/ip6_forward.c
@@ -1428,6 +1428,24 @@ ip6_local_inline (vlib_main_t * vm, vlib_node_runtime_t * node,
? IP6_ERROR_SRC_LOOKUP_MISS : error1);
}
+ /* TODO maybe move to lookup? */
+ vnet_buffer (p0)->ip.fib_index =
+ vec_elt (im->fib_index_by_sw_if_index,
+ vnet_buffer (p0)->sw_if_index[VLIB_RX]);
+ vnet_buffer (p0)->ip.fib_index =
+ (vnet_buffer (p0)->sw_if_index[VLIB_TX] ==
+ (u32) ~ 0) ? vnet_buffer (p0)->ip.
+ fib_index : vnet_buffer (p0)->sw_if_index[VLIB_TX];
+
+ vnet_buffer (p1)->ip.fib_index =
+ vec_elt (im->fib_index_by_sw_if_index,
+ vnet_buffer (p1)->sw_if_index[VLIB_RX]);
+ vnet_buffer (p1)->ip.fib_index =
+ (vnet_buffer (p1)->sw_if_index[VLIB_TX] ==
+ (u32) ~ 0) ? vnet_buffer (p1)->ip.
+ fib_index : vnet_buffer (p1)->sw_if_index[VLIB_TX];
+
+
skip_checks:
next0 = lm->local_next_by_ip_protocol[ip0->protocol];
@@ -1538,6 +1556,14 @@ ip6_local_inline (vlib_main_t * vm, vlib_node_runtime_t * node,
? IP6_ERROR_SRC_LOOKUP_MISS : error0);
}
+ vnet_buffer (p0)->ip.fib_index =
+ vec_elt (im->fib_index_by_sw_if_index,
+ vnet_buffer (p0)->sw_if_index[VLIB_RX]);
+ vnet_buffer (p0)->ip.fib_index =
+ (vnet_buffer (p0)->sw_if_index[VLIB_TX] ==
+ (u32) ~ 0) ? vnet_buffer (p0)->ip.
+ fib_index : vnet_buffer (p0)->sw_if_index[VLIB_TX];
+
skip_check:
next0 = lm->local_next_by_ip_protocol[ip0->protocol];