aboutsummaryrefslogtreecommitdiffstats
path: root/src/plugins/gbp/gbp_subnet.c
diff options
context:
space:
mode:
authorNeale Ranns <neale.ranns@cisco.com>2018-04-04 09:34:50 -0700
committerDamjan Marion <dmarion.lists@gmail.com>2018-04-13 08:51:21 +0000
commit25b049484fcf9161edb2c19250066b893c38c264 (patch)
tree69204352a0648cfc4089fa0e37214bffbae61e81 /src/plugins/gbp/gbp_subnet.c
parent4f8863b21405d1ab3e067e978a60be72a343358b (diff)
GBP V2
update the GBP plugin to implement the full NAT feature set of opflex agent Change-Id: Ic06a039c889445ed0b9087fa1f292634192b0f8d Signed-off-by: Neale Ranns <neale.ranns@cisco.com>
Diffstat (limited to 'src/plugins/gbp/gbp_subnet.c')
-rw-r--r--src/plugins/gbp/gbp_subnet.c176
1 files changed, 176 insertions, 0 deletions
diff --git a/src/plugins/gbp/gbp_subnet.c b/src/plugins/gbp/gbp_subnet.c
new file mode 100644
index 00000000000..b6990844cd3
--- /dev/null
+++ b/src/plugins/gbp/gbp_subnet.c
@@ -0,0 +1,176 @@
+/*
+ * Copyright (c) 2018 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 <plugins/gbp/gbp.h>
+#include <plugins/gbp/gbp_fwd_dpo.h>
+#include <plugins/gbp/gbp_policy_dpo.h>
+
+#include <vnet/fib/fib_table.h>
+#include <vnet/dpo/load_balance.h>
+
+static int
+gbp_internal_subnet_add (u32 fib_index, const fib_prefix_t * pfx)
+{
+ dpo_id_t gfd = DPO_INVALID;
+
+ gbp_fwd_dpo_add_or_lock (fib_proto_to_dpo (pfx->fp_proto), &gfd);
+
+ fib_table_entry_special_dpo_update (fib_index,
+ pfx,
+ FIB_SOURCE_PLUGIN_HI,
+ FIB_ENTRY_FLAG_EXCLUSIVE, &gfd);
+
+ dpo_reset (&gfd);
+
+ return (0);
+}
+
+static int
+gbp_external_subnet_add (u32 fib_index,
+ const fib_prefix_t * pfx,
+ u32 sw_if_index, epg_id_t epg)
+{
+ dpo_id_t gpd = DPO_INVALID;
+
+ gbp_policy_dpo_add_or_lock (fib_proto_to_dpo (pfx->fp_proto),
+ epg, sw_if_index, &gpd);
+
+ fib_table_entry_special_dpo_update (fib_index,
+ pfx,
+ FIB_SOURCE_PLUGIN_HI,
+ (FIB_ENTRY_FLAG_EXCLUSIVE |
+ FIB_ENTRY_FLAG_LOOSE_URPF_EXEMPT),
+ &gpd);
+
+ dpo_reset (&gpd);
+
+ return (0);
+}
+
+static int
+gbp_subnet_del (u32 fib_index, const fib_prefix_t * pfx)
+{
+ fib_table_entry_delete (fib_index, pfx, FIB_SOURCE_PLUGIN_HI);
+
+ return (0);
+}
+
+int
+gbp_subnet_add_del (u32 table_id,
+ const fib_prefix_t * pfx,
+ u32 sw_if_index, epg_id_t epg, u8 is_add, u8 is_internal)
+{
+ u32 fib_index;
+
+ fib_index = fib_table_find (pfx->fp_proto, table_id);
+
+ if (~0 == fib_index)
+ return (VNET_API_ERROR_NO_SUCH_FIB);
+
+ if (is_internal && is_add)
+ return (gbp_internal_subnet_add (fib_index, pfx));
+ else if (!is_internal && is_add)
+ return (gbp_external_subnet_add (fib_index, pfx, sw_if_index, epg));
+
+ return (gbp_subnet_del (fib_index, pfx));
+}
+
+typedef struct gbp_subnet_fib_table_walk_ctx_t_
+{
+ gbp_subnet_cb_t cb;
+ void *ctx;
+} gbp_subnet_fib_table_walk_ctx_t;
+
+static fib_table_walk_rc_t
+gbp_subnet_fib_table_walk (fib_node_index_t fei, void *arg)
+{
+ gbp_subnet_fib_table_walk_ctx_t *ctx = arg;
+ const dpo_id_t *dpo;
+ fib_prefix_t pfx;
+ u32 table_id;
+
+ fib_entry_get_prefix (fei, &pfx);
+ table_id = fib_table_get_table_id (fib_entry_get_fib_index (fei),
+ pfx.fp_proto);
+ dpo = fib_entry_contribute_ip_forwarding (fei);
+
+ if (DPO_LOAD_BALANCE == dpo->dpoi_type)
+ {
+ dpo = load_balance_get_bucket (dpo->dpoi_index, 0);
+
+ if (dpo->dpoi_type == gbp_policy_dpo_get_type ())
+ {
+ gbp_policy_dpo_t *gpd;
+
+ gpd = gbp_policy_dpo_get (dpo->dpoi_index);
+
+ /* *INDENT-OFF* */
+ ctx->cb (table_id, &pfx,
+ gpd->gpd_sw_if_index,
+ gpd->gpd_epg,
+ 0, // is_internal
+ ctx->ctx);
+ /* *INDENT-ON* */
+ }
+ else if (dpo->dpoi_type == gbp_fwd_dpo_get_type ())
+ {
+ /* *INDENT-OFF* */
+ ctx->cb (table_id, &pfx,
+ ~0, // sw_if_index
+ ~0, // epg
+ 1, // is_internal
+ ctx->ctx);
+ /* *INDENT-ON* */
+ }
+ }
+
+ return (FIB_TABLE_WALK_CONTINUE);
+}
+
+void
+gbp_subnet_walk (gbp_subnet_cb_t cb, void *ctx)
+{
+ fib_table_t *fib_table;
+
+ gbp_subnet_fib_table_walk_ctx_t wctx = {
+ .cb = cb,
+ .ctx = ctx,
+ };
+
+ /* *INDENT-OFF* */
+ pool_foreach (fib_table, ip4_main.fibs,
+ ({
+ fib_table_walk(fib_table->ft_index,
+ FIB_PROTOCOL_IP4,
+ gbp_subnet_fib_table_walk,
+ &wctx);
+ }));
+ pool_foreach (fib_table, ip6_main.fibs,
+ ({
+ fib_table_walk(fib_table->ft_index,
+ FIB_PROTOCOL_IP6,
+ gbp_subnet_fib_table_walk,
+ &wctx);
+ }));
+ /* *INDENT-ON* */
+}
+
+/*
+ * fd.io coding-style-patch-verification: ON
+ *
+ * Local Variables:
+ * eval: (c-set-style "gnu")
+ * End:
+ */