summaryrefslogtreecommitdiffstats
path: root/hicn-plugin/src/faces/ip/dpo_ip.c
diff options
context:
space:
mode:
Diffstat (limited to 'hicn-plugin/src/faces/ip/dpo_ip.c')
-rwxr-xr-xhicn-plugin/src/faces/ip/dpo_ip.c187
1 files changed, 187 insertions, 0 deletions
diff --git a/hicn-plugin/src/faces/ip/dpo_ip.c b/hicn-plugin/src/faces/ip/dpo_ip.c
new file mode 100755
index 000000000..1b2dbcff9
--- /dev/null
+++ b/hicn-plugin/src/faces/ip/dpo_ip.c
@@ -0,0 +1,187 @@
+/*
+ * Copyright (c) 2017-2019 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 "dpo_ip.h"
+
+mhash_t hicn_face_ip_local_hashtb;
+mhash_t hicn_face_ip_remote_hashtb;
+dpo_type_t hicn_face_ip_type;
+
+const static char *const hicn_face_ip4dpoi_nodes[] = {
+ "hicn-face-ip4-input",
+ "hicn-face-ip4-output",
+ "hicn-iface-ip4-input",
+ "hicn-iface-ip4-output",
+ NULL,
+};
+
+const static char *const hicn_face_ip6dpoi_nodes[] = {
+ "hicn-face-ip6-input",
+ "hicn-face-ip6-output",
+ "hicn-iface-ip6-input",
+ "hicn-iface-ip6-output",
+ NULL,
+};
+
+const static char *const *const hicn_ip_nodes[DPO_PROTO_NUM] = {
+ [DPO_PROTO_IP4] = hicn_face_ip4dpoi_nodes,
+ [DPO_PROTO_IP6] = hicn_face_ip6dpoi_nodes
+};
+
+const static dpo_vft_t hicn_face_ip_vft = {
+ .dv_lock = hicn_face_lock,
+ .dv_unlock = hicn_face_unlock,
+ .dv_format = format_hicn_face_ip,
+};
+
+/* Must be executed after all the strategy nodes are created */
+void
+hicn_dpo_ip_module_init (void)
+{
+ mhash_init (&hicn_face_ip_local_hashtb,
+ sizeof (hicn_face_id_t) /* value */ ,
+ sizeof (hicn_face_ip_key_t) /* key */ );
+ mhash_init (&hicn_face_ip_remote_hashtb,
+ sizeof (hicn_face_id_t) /* value */ ,
+ sizeof (hicn_face_ip_key_t) /* key */ );
+
+ /*
+ * How much useful is the following registration?
+ * So far it seems that we need it only for setting the dpo_type.
+ */
+ hicn_face_ip_type =
+ dpo_register_new_type (&hicn_face_ip_vft, hicn_ip_nodes);
+}
+
+
+int
+hicn_dpo_ip4_create (dpo_id_t * dpo,
+ const ip4_address_t * local_addr,
+ const ip4_address_t * remote_addr,
+ u32 sw_if,
+ adj_index_t adj,
+ u32 node_index,
+ hicn_face_flags_t flags, hicn_face_id_t * face_id)
+{
+ /* If local matches the dpoi is a face */
+ hicn_face_t *face =
+ hicn_face_ip4_get (local_addr, sw_if, &hicn_face_ip_local_hashtb);
+ u8 is_appface;
+
+ if (face != NULL)
+ return HICN_ERROR_FACE_ALREADY_CREATED;
+
+ face = hicn_face_ip4_get (remote_addr, sw_if, &hicn_face_ip_remote_hashtb);
+
+ if (face == NULL)
+ {
+ hicn_dpo_ip4_add_and_lock_from_remote (dpo, &is_appface, local_addr,
+ remote_addr, sw_if, node_index);
+ *face_id = (hicn_face_id_t) dpo->dpoi_index;
+ face = hicn_dpoi_get_from_idx (*face_id);
+ }
+ else
+ {
+ *face_id = hicn_dpoi_get_index (face);
+ dpo_set (dpo, hicn_face_ip_type, DPO_PROTO_IP4, *face_id);
+ dpo->dpoi_next_node = node_index;
+ }
+
+
+ hicn_face_ip_key_t key;
+ hicn_face_ip4_get_key (local_addr, sw_if, &key);
+
+ mhash_set_mem (&hicn_face_ip_local_hashtb, &key, (uword *) face_id, 0);
+
+ hicn_face_ip_t *ip_face = (hicn_face_ip_t *) face->data;
+ ip46_address_set_ip4 (&ip_face->local_addr, local_addr);
+ ip46_address_set_ip4 (&ip_face->remote_addr, remote_addr);
+ face->shared.flags = flags;
+ face->shared.adj = adj;
+
+ return HICN_ERROR_NONE;
+}
+
+int
+hicn_dpo_ip6_create (dpo_id_t * dpo,
+ const ip6_address_t * local_addr,
+ const ip6_address_t * remote_addr,
+ u32 sw_if,
+ adj_index_t adj,
+ u32 node_index,
+ hicn_face_flags_t flags, hicn_face_id_t * face_id)
+{
+ /* If local matches the dpoi is a face */
+ hicn_face_t *face =
+ hicn_face_ip6_get (local_addr, sw_if, &hicn_face_ip_local_hashtb);
+
+ u8 is_appface;
+
+ if (face != NULL)
+ return HICN_ERROR_FACE_ALREADY_CREATED;
+
+ face = hicn_face_ip6_get (remote_addr, sw_if, &hicn_face_ip_remote_hashtb);
+
+ /* If remote matches the dpoi is a iface */
+ if (face == NULL)
+ {
+ hicn_dpo_ip6_add_and_lock_from_remote (dpo, &is_appface, local_addr,
+ remote_addr, sw_if, node_index);
+ *face_id = (hicn_face_id_t) dpo->dpoi_index;
+ face = hicn_dpoi_get_from_idx (*face_id);
+ }
+ else
+ {
+ *face_id = hicn_dpoi_get_index (face);
+ dpo_set (dpo, hicn_face_ip_type, DPO_PROTO_IP6, *face_id);
+ dpo->dpoi_next_node = node_index;
+ }
+
+ hicn_face_ip_key_t key;
+ hicn_face_ip6_get_key (local_addr, sw_if, &key);
+
+ mhash_set_mem (&hicn_face_ip_local_hashtb, &key, (uword *) face_id, 0);
+
+ hicn_face_ip_t *ip_face = (hicn_face_ip_t *) face->data;
+ clib_memcpy (&ip_face->local_addr, local_addr, sizeof (ip6_address_t));
+ clib_memcpy (&ip_face->remote_addr, remote_addr, sizeof (ip6_address_t));
+ face->shared.sw_if = sw_if;
+ face->shared.flags = flags;
+ face->shared.adj = adj;
+
+
+ return HICN_ERROR_NONE;
+}
+
+void
+hicn_dpo_ip_create_from_face (hicn_face_t * face, dpo_id_t * dpo,
+ u16 dpoi_next_node)
+{
+ hicn_face_id_t face_dpoi_id = hicn_dpoi_get_index (face);
+ hicn_face_ip_t *ip_face = (hicn_face_ip_t *) face->data;
+ dpo_set (dpo, face->shared.face_type,
+ ip46_address_is_ip4 (&ip_face->
+ local_addr) ? DPO_PROTO_IP4 : DPO_PROTO_IP6,
+ face_dpoi_id);
+ dpo->dpoi_next_node = dpoi_next_node;
+}
+
+/*
+ * fd.io coding-style-patch-verification: ON
+ *
+ * Local Variables:
+ * eval: (c-set-style "gnu")
+ * End:
+ */