2 * Copyright (c) 2016 Cisco and/or its affiliates.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at:
7 * http://www.apache.org/licenses/LICENSE-2.0
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
16 #include <vnet/mfib/mfib_types.h>
18 #include <vnet/ip/ip.h>
21 * String names for each flag
23 static const char *mfib_flag_names[] = MFIB_ENTRY_NAMES_SHORT;
24 static const char *mfib_flag_names_long[] = MFIB_ENTRY_NAMES_LONG;
26 static const char *mfib_itf_flag_long_names[] = MFIB_ITF_NAMES_LONG;
27 static const char *mfib_itf_flag_names[] = MFIB_ITF_NAMES_SHORT;
30 mfib_prefix_is_cover (const mfib_prefix_t *p1,
31 const mfib_prefix_t *p2)
33 if (!ip46_address_is_equal(&p1->fp_src_addr, &p2->fp_src_addr))
38 case FIB_PROTOCOL_IP4:
39 return (ip4_destination_matches_route(&ip4_main,
43 case FIB_PROTOCOL_IP6:
44 return (ip6_destination_matches_route(&ip6_main,
48 case FIB_PROTOCOL_MPLS:
55 mfib_prefix_is_host (const mfib_prefix_t *pfx)
57 switch (pfx->fp_proto)
59 case FIB_PROTOCOL_IP4:
60 return (64 == pfx->fp_len);
61 case FIB_PROTOCOL_IP6:
62 return (256 == pfx->fp_len);
63 case FIB_PROTOCOL_MPLS:
70 fib_forward_chain_type_t
71 mfib_forw_chain_type_from_dpo_proto (dpo_proto_t proto)
76 return (FIB_FORW_CHAIN_TYPE_MCAST_IP4);
78 return (FIB_FORW_CHAIN_TYPE_MCAST_IP6);
80 case DPO_PROTO_ETHERNET:
86 return (FIB_FORW_CHAIN_TYPE_MCAST_IP4);
89 fib_forward_chain_type_t
90 mfib_forw_chain_type_from_fib_proto (fib_protocol_t proto)
94 case FIB_PROTOCOL_IP4:
95 return (FIB_FORW_CHAIN_TYPE_MCAST_IP4);
96 case FIB_PROTOCOL_IP6:
97 return (FIB_FORW_CHAIN_TYPE_MCAST_IP6);
98 case FIB_PROTOCOL_MPLS:
102 return (FIB_FORW_CHAIN_TYPE_MCAST_IP4);
106 format_mfib_prefix (u8 * s, va_list * args)
108 mfib_prefix_t *fp = va_arg (*args, mfib_prefix_t *);
111 * protocol specific so it prints ::/0 correctly.
113 switch (fp->fp_proto)
115 case FIB_PROTOCOL_IP6:
117 ip6_address_t p6 = fp->fp_grp_addr.ip6;
118 u32 len = (fp->fp_len > 128 ? 128 : fp->fp_len);
120 ip6_address_mask(&p6, &(ip6_main.fib_masks[len]));
122 if (ip6_address_is_zero(&fp->fp_src_addr.ip6))
124 s = format(s, "(*, ");
128 s = format (s, "(%U, ", format_ip6_address, &fp->fp_src_addr.ip6);
130 s = format (s, "%U", format_ip6_address, &p6);
131 s = format (s, "/%d)", len);
134 case FIB_PROTOCOL_IP4:
136 ip4_address_t p4 = fp->fp_grp_addr.ip4;
137 u32 len = (fp->fp_len > 32 ? 32 : fp->fp_len);
139 p4.as_u32 &= ip4_main.fib_masks[len];
141 if (0 == fp->fp_src_addr.ip4.as_u32)
143 s = format(s, "(*, ");
147 s = format (s, "(%U, ", format_ip4_address, &fp->fp_src_addr.ip4);
149 s = format (s, "%U", format_ip4_address, &p4);
150 s = format (s, "/%d)", len);
153 case FIB_PROTOCOL_MPLS:
161 format_mfib_entry_flags (u8 * s, va_list * args)
163 mfib_entry_attribute_t attr;
164 mfib_entry_flags_t flags;
166 flags = va_arg (*args, mfib_entry_flags_t);
168 if (MFIB_ENTRY_FLAG_NONE != flags) {
169 s = format(s, " flags:");
170 FOR_EACH_MFIB_ATTRIBUTE(attr) {
171 if ((1<<attr) & flags) {
172 s = format (s, "%s,", mfib_flag_names_long[attr]);
181 format_mfib_itf_flags (u8 * s, va_list * args)
183 mfib_itf_attribute_t attr;
184 mfib_itf_flags_t flags;
186 flags = va_arg (*args, mfib_itf_flags_t);
188 FOR_EACH_MFIB_ITF_ATTRIBUTE(attr) {
189 if ((1<<attr) & flags) {
190 s = format (s, "%s,", mfib_itf_flag_long_names[attr]);
198 unformat_mfib_itf_flags (unformat_input_t * input,
201 mfib_itf_flags_t old, *iflags = va_arg (*args, mfib_itf_flags_t*);
202 mfib_itf_attribute_t attr;
205 FOR_EACH_MFIB_ITF_ATTRIBUTE(attr) {
206 if (unformat (input, mfib_itf_flag_long_names[attr]))
207 *iflags |= (1 << attr);
209 FOR_EACH_MFIB_ITF_ATTRIBUTE(attr) {
210 if (unformat (input, mfib_itf_flag_names[attr]))
211 *iflags |= (1 << attr);
214 return (old == *iflags ? 0 : 1);
218 unformat_mfib_entry_flags (unformat_input_t * input,
221 mfib_entry_flags_t old, *eflags = va_arg (*args, mfib_entry_flags_t*);
222 mfib_entry_attribute_t attr;
225 FOR_EACH_MFIB_ATTRIBUTE(attr) {
226 if (unformat (input, mfib_flag_names_long[attr]))
227 *eflags |= (1 << attr);
229 FOR_EACH_MFIB_ATTRIBUTE(attr) {
230 if (unformat (input, mfib_flag_names[attr]))
231 *eflags |= (1 << attr);
234 return (old == *eflags ? 0 : 1);
238 mfib_show_route_flags (vlib_main_t * vm,
239 unformat_input_t * main_input,
240 vlib_cli_command_t * cmd)
242 mfib_entry_attribute_t attr;
244 FOR_EACH_MFIB_ATTRIBUTE(attr) {
245 vlib_cli_output(vm, "%s = %s",
246 mfib_flag_names[attr],
247 mfib_flag_names_long[attr]);
254 * This command displays the set of supported flags applicable to an MFIB route
257 VLIB_CLI_COMMAND (mfib_route_flags_command, static) =
259 .path = "show mfib route flags",
260 .short_help = "Flags applicable to an MFIB route",
261 .function = mfib_show_route_flags,
267 mfib_show_itf_flags (vlib_main_t * vm,
268 unformat_input_t * main_input,
269 vlib_cli_command_t * cmd)
271 mfib_itf_attribute_t attr;
273 FOR_EACH_MFIB_ITF_ATTRIBUTE(attr) {
274 vlib_cli_output(vm, "%s = %s",
275 mfib_itf_flag_names[attr],
276 mfib_itf_flag_long_names[attr]);
283 * This command displays the set of supported flags applicable to an MFIB interface
286 VLIB_CLI_COMMAND (mfib_itf_flags_command, static) =
288 .path = "show mfib itf flags",
289 .short_help = "Flags applicable to an MFIB interfaces",
290 .function = mfib_show_itf_flags,