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/fib/fib_source.h>
18 static const char *fib_source_names[] = FIB_SOURCES;
19 static const char *fib_source_behaviour_names[] = FIB_SOURCE_BEHAVIOURS;
21 static fib_source_t fib_source_id = FIB_SOURCE_LAST+1;
23 typedef struct fib_source_prio_t_
25 fib_source_priority_t fsp_class;
26 fib_source_priority_t fsp_slot;
30 * for each client requested priority count the number pf uses of
31 * that prio so we can asign is usage a slot number, and therefore
32 * each request will have a unique value.
34 STATIC_ASSERT_SIZEOF(fib_source_priority_t, 1);
35 static fib_source_priority_t fib_source_prio_by_class[0x100];
37 typedef struct fib_source_reg_t_
39 fib_source_t fsr_source;
41 fib_source_behaviour_t fsr_behaviour;
42 fib_source_prio_t fsr_prio;
45 static fib_source_reg_t *fib_source_regs;
49 fib_source_get_prio (fib_source_t src)
51 ASSERT(vec_len(fib_source_regs) > src);
53 return (((u16)fib_source_regs[src].fsr_prio.fsp_class << 8) |
54 fib_source_regs[src].fsr_prio.fsp_slot);
57 fib_source_behaviour_t
58 fib_source_get_behaviour (fib_source_t src)
60 ASSERT(vec_len(fib_source_regs) > src);
62 return (fib_source_regs[src].fsr_behaviour);
66 format_fib_source (u8 *s, va_list *a)
68 fib_source_t src = va_arg(*a, int);
70 ASSERT(vec_len(fib_source_regs) > src);
72 return (format(s, "%s", fib_source_regs[src].fsr_name));
75 fib_source_priority_cmp_t
76 fib_source_cmp (fib_source_t s1,
79 if (fib_source_get_prio(s1) <
80 fib_source_get_prio(s2))
82 return (FIB_SOURCE_CMP_BETTER);
84 else if (fib_source_get_prio(s1) >
85 fib_source_get_prio(s2))
87 return (FIB_SOURCE_CMP_WORSE);
89 return (FIB_SOURCE_CMP_EQUAL);
93 fib_source_reg_init (fib_source_t src,
95 fib_source_priority_t prio,
96 fib_source_behaviour_t bh)
98 fib_source_priority_t slot;
99 fib_source_reg_t *fsr;
102 * ensure we assign a unique priority to each request
103 * otherwise different source will be treated like ECMP
105 slot = fib_source_prio_by_class[prio]++;
107 vec_validate(fib_source_regs, src);
109 fsr = &fib_source_regs[src];
110 fsr->fsr_source = src;
111 fsr->fsr_name = strdup(name);
112 fsr->fsr_prio.fsp_class = prio;
113 fsr->fsr_prio.fsp_slot = slot;
114 fsr->fsr_behaviour = bh;
118 fib_source_allocate (const char *name,
119 fib_source_priority_t prio,
120 fib_source_behaviour_t bh)
125 ASSERT(fib_source_id < 255);
126 if (fib_source_id == 255)
127 return (FIB_SOURCE_INVALID);
129 src = fib_source_id++;
131 fib_source_reg_init(src, name, prio, bh);
137 fib_source_register (fib_source_t src,
138 fib_source_priority_t prio,
139 fib_source_behaviour_t bh)
141 fib_source_reg_init(src, fib_source_names[src], prio, bh);
145 format_fib_source_reg (u8 *s, va_list *a)
147 fib_source_reg_t *fsr = va_arg(*a, fib_source_reg_t*);
149 s = format(s, "[%d] %U prio:%d.%d behaviour:%s",
151 format_fib_source, fsr->fsr_source,
152 fsr->fsr_prio.fsp_class, fsr->fsr_prio.fsp_slot,
153 fib_source_behaviour_names[fsr->fsr_behaviour]);
159 fib_source_reg_cmp_for_sort (void * v1,
162 fib_source_reg_t *fsr1 = v1, *fsr2 = v2;
164 return (fib_source_get_prio(fsr1->fsr_source) -
165 fib_source_get_prio(fsr2->fsr_source));
169 fib_source_walk (fib_source_walk_t fn,
172 fib_source_reg_t *fsr;
174 vec_foreach(fsr, fib_source_regs)
176 if (WALK_STOP == fn(fsr->fsr_source,
178 fsr->fsr_prio.fsp_class,
185 static clib_error_t *
186 fib_source_show (vlib_main_t * vm,
187 unformat_input_t * input,
188 vlib_cli_command_t * cmd)
190 fib_source_reg_t *fsr, *fsrs;
192 fsrs = vec_dup(fib_source_regs);
194 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
196 if (unformat (input, "prio") ||
197 unformat (input, "priority"))
198 vec_sort_with_function(fsrs, fib_source_reg_cmp_for_sort);
200 vec_foreach(fsr, fsrs)
202 vlib_cli_output(vm, "%U", format_fib_source_reg, fsr);
209 VLIB_CLI_COMMAND (show_fib_sources, static) = {
210 .path = "show fib source",
211 .function = fib_source_show,
212 .short_help = "show fib source [prio]",
217 fib_source_module_init (void)
219 #define _(s,p,b) fib_source_register(s,p,b);