Line data Source code
1 : /*
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:
6 : *
7 : * http://www.apache.org/licenses/LICENSE-2.0
8 : *
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.
14 : */
15 :
16 : #include <vnet/mfib/mfib_types.h>
17 :
18 : #include <vnet/ip/ip.h>
19 :
20 : /**
21 : * String names for each flag
22 : */
23 : static const char *mfib_flag_names[] = MFIB_ENTRY_NAMES_SHORT;
24 : static const char *mfib_flag_names_long[] = MFIB_ENTRY_NAMES_LONG;
25 :
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;
28 :
29 : int
30 2 : mfib_prefix_is_cover (const mfib_prefix_t *p1,
31 : const mfib_prefix_t *p2)
32 : {
33 2 : if (!ip46_address_is_equal(&p1->fp_src_addr, &p2->fp_src_addr))
34 0 : return (0);
35 :
36 2 : switch (p1->fp_proto)
37 : {
38 1 : case FIB_PROTOCOL_IP4:
39 1 : return (ip4_destination_matches_route(&ip4_main,
40 : &p1->fp_grp_addr.ip4,
41 : &p2->fp_grp_addr.ip4,
42 1 : p1->fp_len));
43 1 : case FIB_PROTOCOL_IP6:
44 1 : return (ip6_destination_matches_route(&ip6_main,
45 : &p1->fp_grp_addr.ip6,
46 : &p2->fp_grp_addr.ip6,
47 1 : p1->fp_len));
48 0 : case FIB_PROTOCOL_MPLS:
49 0 : break;
50 : }
51 0 : return (0);
52 : }
53 :
54 : int
55 7073 : mfib_prefix_is_host (const mfib_prefix_t *pfx)
56 : {
57 7073 : switch (pfx->fp_proto)
58 : {
59 4127 : case FIB_PROTOCOL_IP4:
60 4127 : return (64 == pfx->fp_len);
61 2946 : case FIB_PROTOCOL_IP6:
62 2946 : return (256 == pfx->fp_len);
63 0 : case FIB_PROTOCOL_MPLS:
64 0 : ASSERT(0);
65 0 : break;
66 : }
67 0 : return (0);
68 : }
69 :
70 : fib_forward_chain_type_t
71 76 : mfib_forw_chain_type_from_dpo_proto (dpo_proto_t proto)
72 : {
73 76 : switch (proto)
74 : {
75 38 : case DPO_PROTO_IP4:
76 38 : return (FIB_FORW_CHAIN_TYPE_MCAST_IP4);
77 38 : case DPO_PROTO_IP6:
78 38 : return (FIB_FORW_CHAIN_TYPE_MCAST_IP6);
79 0 : case DPO_PROTO_MPLS:
80 : case DPO_PROTO_ETHERNET:
81 : case DPO_PROTO_NSH:
82 : case DPO_PROTO_BIER:
83 0 : break;
84 : }
85 0 : ASSERT(0);
86 0 : return (FIB_FORW_CHAIN_TYPE_MCAST_IP4);
87 : }
88 :
89 : fib_forward_chain_type_t
90 68 : mfib_forw_chain_type_from_fib_proto (fib_protocol_t proto)
91 : {
92 68 : switch (proto)
93 : {
94 34 : case FIB_PROTOCOL_IP4:
95 34 : return (FIB_FORW_CHAIN_TYPE_MCAST_IP4);
96 34 : case FIB_PROTOCOL_IP6:
97 34 : return (FIB_FORW_CHAIN_TYPE_MCAST_IP6);
98 0 : case FIB_PROTOCOL_MPLS:
99 0 : break;
100 : }
101 0 : ASSERT(0);
102 0 : return (FIB_FORW_CHAIN_TYPE_MCAST_IP4);
103 : }
104 :
105 : u8 *
106 7 : format_mfib_prefix (u8 * s, va_list * args)
107 : {
108 7 : mfib_prefix_t *fp = va_arg (*args, mfib_prefix_t *);
109 :
110 : /*
111 : * protocol specific so it prints ::/0 correctly.
112 : */
113 7 : switch (fp->fp_proto)
114 : {
115 1 : case FIB_PROTOCOL_IP6:
116 : {
117 1 : ip6_address_t p6 = fp->fp_grp_addr.ip6;
118 1 : u32 len = (fp->fp_len > 128 ? 128 : fp->fp_len);
119 :
120 1 : ip6_address_mask(&p6, &(ip6_main.fib_masks[len]));
121 :
122 1 : if (ip6_address_is_zero(&fp->fp_src_addr.ip6))
123 : {
124 1 : s = format(s, "(*, ");
125 : }
126 : else
127 : {
128 0 : s = format (s, "(%U, ", format_ip6_address, &fp->fp_src_addr.ip6);
129 : }
130 1 : s = format (s, "%U", format_ip6_address, &p6);
131 1 : s = format (s, "/%d)", len);
132 1 : break;
133 : }
134 6 : case FIB_PROTOCOL_IP4:
135 : {
136 6 : ip4_address_t p4 = fp->fp_grp_addr.ip4;
137 6 : u32 len = (fp->fp_len > 32 ? 32 : fp->fp_len);
138 :
139 6 : p4.as_u32 &= ip4_main.fib_masks[len];
140 :
141 6 : if (0 == fp->fp_src_addr.ip4.as_u32)
142 : {
143 6 : s = format(s, "(*, ");
144 : }
145 : else
146 : {
147 0 : s = format (s, "(%U, ", format_ip4_address, &fp->fp_src_addr.ip4);
148 : }
149 6 : s = format (s, "%U", format_ip4_address, &p4);
150 6 : s = format (s, "/%d)", len);
151 6 : break;
152 : }
153 0 : case FIB_PROTOCOL_MPLS:
154 0 : break;
155 : }
156 :
157 7 : return (s);
158 : }
159 :
160 : u8 *
161 6 : format_mfib_entry_flags (u8 * s, va_list * args)
162 : {
163 : mfib_entry_attribute_t attr;
164 : mfib_entry_flags_t flags;
165 :
166 6 : flags = va_arg (*args, mfib_entry_flags_t);
167 :
168 6 : if (MFIB_ENTRY_FLAG_NONE != flags) {
169 1 : s = format(s, " flags:");
170 7 : FOR_EACH_MFIB_ATTRIBUTE(attr) {
171 6 : if ((1<<attr) & flags) {
172 1 : s = format (s, "%s,", mfib_flag_names_long[attr]);
173 : }
174 : }
175 : }
176 :
177 6 : return (s);
178 : }
179 :
180 : u8 *
181 3918 : format_mfib_itf_flags (u8 * s, va_list * args)
182 : {
183 : mfib_itf_attribute_t attr;
184 : mfib_itf_flags_t flags;
185 :
186 3918 : flags = va_arg (*args, mfib_itf_flags_t);
187 :
188 23508 : FOR_EACH_MFIB_ITF_ATTRIBUTE(attr) {
189 19590 : if ((1<<attr) & flags) {
190 3433 : s = format (s, "%s,", mfib_itf_flag_long_names[attr]);
191 : }
192 : }
193 :
194 3918 : return (s);
195 : }
196 :
197 : uword
198 2 : unformat_mfib_itf_flags (unformat_input_t * input,
199 : va_list * args)
200 : {
201 2 : mfib_itf_flags_t old, *iflags = va_arg (*args, mfib_itf_flags_t*);
202 : mfib_itf_attribute_t attr;
203 :
204 2 : old = *iflags;
205 12 : FOR_EACH_MFIB_ITF_ATTRIBUTE(attr) {
206 10 : if (unformat (input, mfib_itf_flag_long_names[attr]))
207 0 : *iflags |= (1 << attr);
208 : }
209 12 : FOR_EACH_MFIB_ITF_ATTRIBUTE(attr) {
210 10 : if (unformat (input, mfib_itf_flag_names[attr]))
211 0 : *iflags |= (1 << attr);
212 : }
213 :
214 2 : return (old == *iflags ? 0 : 1);
215 : }
216 :
217 : uword
218 0 : unformat_mfib_entry_flags (unformat_input_t * input,
219 : va_list * args)
220 : {
221 0 : mfib_entry_flags_t old, *eflags = va_arg (*args, mfib_entry_flags_t*);
222 : mfib_entry_attribute_t attr;
223 :
224 0 : old = *eflags;
225 0 : FOR_EACH_MFIB_ATTRIBUTE(attr) {
226 0 : if (unformat (input, mfib_flag_names_long[attr]))
227 0 : *eflags |= (1 << attr);
228 : }
229 0 : FOR_EACH_MFIB_ATTRIBUTE(attr) {
230 0 : if (unformat (input, mfib_flag_names[attr]))
231 0 : *eflags |= (1 << attr);
232 : }
233 :
234 0 : return (old == *eflags ? 0 : 1);
235 : }
236 :
237 : clib_error_t *
238 0 : mfib_show_route_flags (vlib_main_t * vm,
239 : unformat_input_t * main_input,
240 : vlib_cli_command_t * cmd)
241 : {
242 : mfib_entry_attribute_t attr;
243 :
244 0 : FOR_EACH_MFIB_ATTRIBUTE(attr) {
245 0 : vlib_cli_output(vm, "%s = %s",
246 : mfib_flag_names[attr],
247 : mfib_flag_names_long[attr]);
248 : }
249 :
250 0 : return (NULL);
251 : }
252 :
253 : /*?
254 : * This command displays the set of supported flags applicable to an MFIB route
255 : */
256 : /* *INDENT-OFF* */
257 272887 : VLIB_CLI_COMMAND (mfib_route_flags_command, static) =
258 : {
259 : .path = "show mfib route flags",
260 : .short_help = "Flags applicable to an MFIB route",
261 : .function = mfib_show_route_flags,
262 : .is_mp_safe = 1,
263 : };
264 : /* *INDENT-ON* */
265 :
266 : clib_error_t *
267 0 : mfib_show_itf_flags (vlib_main_t * vm,
268 : unformat_input_t * main_input,
269 : vlib_cli_command_t * cmd)
270 : {
271 : mfib_itf_attribute_t attr;
272 :
273 0 : FOR_EACH_MFIB_ITF_ATTRIBUTE(attr) {
274 0 : vlib_cli_output(vm, "%s = %s",
275 : mfib_itf_flag_names[attr],
276 : mfib_itf_flag_long_names[attr]);
277 : }
278 :
279 0 : return (NULL);
280 : }
281 :
282 : /*?
283 : * This command displays the set of supported flags applicable to an MFIB interface
284 : */
285 : /* *INDENT-OFF* */
286 272887 : VLIB_CLI_COMMAND (mfib_itf_flags_command, static) =
287 : {
288 : .path = "show mfib itf flags",
289 : .short_help = "Flags applicable to an MFIB interfaces",
290 : .function = mfib_show_itf_flags,
291 : .is_mp_safe = 1,
292 : };
293 : /* *INDENT-ON* */
|