/* * Copyright (c) 2016 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 /** * String names for each flag */ static const char *mfib_flag_names[] = MFIB_ENTRY_NAMES_SHORT; static const char *mfib_flag_names_long[] = MFIB_ENTRY_NAMES_LONG; static const char *mfib_itf_flag_long_names[] = MFIB_ITF_NAMES_LONG; static const char *mfib_itf_flag_names[] = MFIB_ITF_NAMES_SHORT; int mfib_prefix_is_cover (const mfib_prefix_t *p1, const mfib_prefix_t *p2) { if (!ip46_address_is_equal(&p1->fp_src_addr, &p2->fp_src_addr)) return (0); switch (p1->fp_proto) { case FIB_PROTOCOL_IP4: return (ip4_destination_matches_route(&ip4_main, &p1->fp_grp_addr.ip4, &p2->fp_grp_addr.ip4, p1->fp_len)); case FIB_PROTOCOL_IP6: return (ip6_destination_matches_route(&ip6_main, &p1->fp_grp_addr.ip6, &p2->fp_grp_addr.ip6, p1->fp_len)); case FIB_PROTOCOL_MPLS: break; } return (0); } int mfib_prefix_is_host (const mfib_prefix_t *pfx) { switch (pfx->fp_proto) { case FIB_PROTOCOL_IP4: return (64 == pfx->fp_len); case FIB_PROTOCOL_IP6: return (256 == pfx->fp_len); case FIB_PROTOCOL_MPLS: ASSERT(0); break; } return (0); } fib_forward_chain_type_t mfib_forw_chain_type_from_dpo_proto (dpo_proto_t proto) { switch (proto) { case DPO_PROTO_IP4: return (FIB_FORW_CHAIN_TYPE_MCAST_IP4); case DPO_PROTO_IP6: return (FIB_FORW_CHAIN_TYPE_MCAST_IP6); case DPO_PROTO_MPLS: case DPO_PROTO_ETHERNET: case DPO_PROTO_NSH: case DPO_PROTO_BIER: break; } ASSERT(0); return (FIB_FORW_CHAIN_TYPE_MCAST_IP4); } fib_forward_chain_type_t mfib_forw_chain_type_from_fib_proto (fib_protocol_t proto) { switch (proto) { case FIB_PROTOCOL_IP4: return (FIB_FORW_CHAIN_TYPE_MCAST_IP4); case FIB_PROTOCOL_IP6: return (FIB_FORW_CHAIN_TYPE_MCAST_IP6); case FIB_PROTOCOL_MPLS: break; } ASSERT(0); return (FIB_FORW_CHAIN_TYPE_MCAST_IP4); } u8 * format_mfib_prefix (u8 * s, va_list * args) { mfib_prefix_t *fp = va_arg (*args, mfib_prefix_t *); /* * protocol specific so it prints ::/0 correctly. */ switch (fp->fp_proto) { case FIB_PROTOCOL_IP6: { ip6_address_t p6 = fp->fp_grp_addr.ip6; u32 len = (fp->fp_len > 128 ? 128 : fp->fp_len); ip6_address_mask(&p6, &(ip6_main.fib_masks[len])); if (ip6_address_is_zero(&fp->fp_src_addr.ip6)) { s = format(s, "(*, "); } else { s = format (s, "(%U, ", format_ip6_address, &fp->fp_src_addr.ip6); } s = format (s, "%U", format_ip6_address, &p6); s = format (s, "/%d)", len); break; } case FIB_PROTOCOL_IP4: { ip4_address_t p4 = fp->fp_grp_addr.ip4; u32 len = (fp->fp_len > 32 ? 32 : fp->fp_len); p4.as_u32 &= ip4_main.fib_masks[len]; if (0 == fp->fp_src_addr.ip4.as_u32) { s = format(s, "(*, "); } else { s = format (s, "(%U, ", format_ip4_address, &fp->fp_src_addr.ip4); } s = format (s, "%U", format_ip4_address, &p4); s = format (s, "/%d)", len); break; } case FIB_PROTOCOL_MPLS: break; } return (s); } u8 * format_mfib_entry_flags (u8 * s, va_list * args) { mfib_entry_attribute_t attr; mfib_entry_flags_t flags; flags = va_arg (*args, mfib_entry_flags_t); if (MFIB_ENTRY_FLAG_NONE != flags) { s = format(s, " flags:"); FOR_EACH_MFIB_ATTRIBUTE(attr) { if ((1<