X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fplugins%2Fgbp%2Fgbp_subnet.c;fp=src%2Fplugins%2Fgbp%2Fgbp_subnet.c;h=b6990844cd3f689f45ddac8c890795e1cef009e4;hb=25b049484fcf9161edb2c19250066b893c38c264;hp=0000000000000000000000000000000000000000;hpb=4f8863b21405d1ab3e067e978a60be72a343358b;p=vpp.git 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 +#include +#include + +#include +#include + +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: + */