BIER in non-MPLS netowrks
[vpp.git] / src / vnet / bier / bier_types.c
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 <vppinfra/types.h>
17 #include <vnet/bier/bier_types.h>
18 #include <vnet/bier/bier_hdr_inlines.h>
19
20 /*
21  * enum to string conversions
22  */
23 const static char* const bier_hdr_len_id_names[] = BIER_HDR_LEN_IDS;
24 const static char* const bier_hdr_proto_names[] = BIER_HDR_PROTO_ID_NAMES;
25
26 const static u16 bier_hdr_len_num_buckets[] = {
27     [BIER_HDR_LEN_INVALID] = 0,
28     [BIER_HDR_LEN_64] = 8,
29     [BIER_HDR_LEN_128] = 16,
30     [BIER_HDR_LEN_256] = 32,
31     [BIER_HDR_LEN_512] = 64,
32     [BIER_HDR_LEN_1024] = 128,
33     [BIER_HDR_LEN_2048] = 256,
34     [BIER_HDR_LEN_4096] = 512,
35 };
36
37 const static u16 bier_hdr_len_num_bits[] = {
38     [BIER_HDR_LEN_INVALID] = 0,
39     [BIER_HDR_LEN_64] = 64,
40     [BIER_HDR_LEN_128] = 128,
41     [BIER_HDR_LEN_256] = 256,
42     [BIER_HDR_LEN_512] = 512,
43     [BIER_HDR_LEN_1024] = 1024,
44     [BIER_HDR_LEN_2048] = 2048,
45     [BIER_HDR_LEN_4096] = 4096,
46 };
47
48 const static u16 bier_hdr_len_prefix_len[] = {
49     [BIER_HDR_LEN_INVALID] = 0,
50     [BIER_HDR_LEN_64] = 7,
51     [BIER_HDR_LEN_128] = 8,
52     [BIER_HDR_LEN_256] = 9,
53     [BIER_HDR_LEN_512] = 10,
54     [BIER_HDR_LEN_1024] = 11,
55     [BIER_HDR_LEN_2048] = 12,
56     [BIER_HDR_LEN_4096] = 13,
57 };
58
59 u32
60 bier_hdr_len_id_to_num_buckets (bier_hdr_len_id_t id)
61 {
62     return (bier_hdr_len_num_buckets[id]);
63 }
64
65 u32
66 bier_hdr_len_id_to_num_bytes (bier_hdr_len_id_t id)
67 {
68     return (bier_hdr_len_id_to_num_buckets(id));
69 }
70
71 u32
72 bier_hdr_len_id_to_max_bucket (bier_hdr_len_id_t id)
73 {
74     return (bier_hdr_len_id_to_num_buckets(id) - 1);
75 }
76
77 u32
78 bier_hdr_len_id_to_num_bits (bier_hdr_len_id_t id)
79 {
80     return (bier_hdr_len_num_bits[id]);
81 }
82
83 u32
84 bier_hdr_len_id_to_max_bit (bier_hdr_len_id_t id)
85 {
86     return (bier_hdr_len_id_to_num_bits(id));
87 }
88
89 u32
90 bier_hdr_len_id_to_prefix_len (bier_hdr_len_id_t id)
91 {
92     return (bier_hdr_len_prefix_len[id]);
93 }
94
95 u8 *
96 format_bier_hdr_len_id (u8 *s, va_list *ap)
97 {
98     bier_hdr_len_id_t hli = va_arg(*ap, int); // int promotion of bier_hdr_len_id_t
99
100     return (format(s, "%s", bier_hdr_len_id_names[hli]));
101 }
102
103 u8 *
104 format_bier_hdr_proto (u8 *s, va_list *ap)
105 {
106     bier_hdr_proto_id_t pi = va_arg(*ap, int);
107
108     return (format(s, "%s", bier_hdr_proto_names[pi]));
109 }
110
111 int
112 bier_table_id_cmp (const bier_table_id_t *btid1,
113                    const bier_table_id_t *btid2)
114 {
115     int res;
116
117     res = (btid1->bti_set - btid2->bti_set);
118
119     if (0 == res)
120     {
121         res  = (btid1->bti_sub_domain - btid2->bti_sub_domain);
122     }
123     if (0 == res)
124     {
125         res = (btid1->bti_ecmp - btid2->bti_ecmp);
126     }
127     if (0 == res)
128     {
129         res = (btid1->bti_hdr_len - btid2->bti_hdr_len);
130     }
131     if (0 == res)
132     {
133         res = (btid1->bti_type - btid2->bti_type);
134     }
135     return (res);
136 }
137
138 dpo_proto_t
139 bier_hdr_proto_to_dpo (bier_hdr_proto_id_t bproto)
140 {
141     switch (bproto)
142     {
143     case BIER_HDR_PROTO_INVALID:
144     case BIER_HDR_PROTO_CTRL:
145     case BIER_HDR_PROTO_OAM:
146         ASSERT(0);
147         break;
148     case BIER_HDR_PROTO_MPLS_DOWN_STREAM:
149     case BIER_HDR_PROTO_MPLS_UP_STREAM:
150         return (DPO_PROTO_MPLS);
151     case BIER_HDR_PROTO_ETHERNET:
152     case BIER_HDR_PROTO_VXLAN:
153         return (DPO_PROTO_ETHERNET);
154     case BIER_HDR_PROTO_IPV4:
155         return (DPO_PROTO_IP4);
156     case BIER_HDR_PROTO_IPV6:
157         return (DPO_PROTO_IP4);
158     }
159
160     return (DPO_PROTO_NUM);
161 }
162
163 bier_bift_id_t
164 bier_bift_id_encode (bier_table_set_id_t set,
165                      bier_table_sub_domain_id_t sd,
166                      bier_hdr_len_id_t bsl)
167 {
168     bier_bift_id_t id;
169
170     id = bsl;
171     id = id << 8;
172     id |= sd;
173     id = id << 8;
174     id |= set;
175
176     return (id);
177 }
178
179 void
180 bier_bift_id_decode (bier_bift_id_t id,
181                      bier_table_set_id_t *set,
182                      bier_table_sub_domain_id_t *sd,
183                      bier_hdr_len_id_t *bsl)
184 {
185     *set = id & 0xff;
186     id = id >> 8;
187     *sd = id & 0xff;
188     id = id >> 8;
189     *bsl = id;
190 }
191
192 u8 *
193 format_bier_table_id (u8 *s, va_list *ap)
194 {
195     bier_table_id_t *btid = va_arg(*ap, bier_table_id_t *);
196
197     return (format(s, "sub-domain:%d set:%d ecmp:%d bsl:%U",
198                    btid->bti_sub_domain,
199                    btid->bti_set,
200                    btid->bti_ecmp,
201                    format_bier_hdr_len_id, btid->bti_hdr_len));
202 }
203
204 u8 *
205 format_bier_hdr (u8 *s, va_list *ap)
206 {
207     bier_hdr_t *bh = va_arg(*ap, bier_hdr_t *);
208     bier_hdr_t copy = *bh;
209
210     bier_hdr_ntoh(&copy);
211
212     return (format(s, "nibble:%d version:%d hdr-len:%U entropy:%d proto:%U src:%d",
213                    bier_hdr_get_1st_nibble(&copy),
214                    bier_hdr_get_version(&copy),
215                    format_bier_hdr_len_id, bier_hdr_get_len_id(&copy),
216                    bier_hdr_get_entropy(&copy),
217                    format_bier_hdr_proto, bier_hdr_get_proto_id(&copy),
218                    bier_hdr_get_src_id(&copy)));
219 }
220
221  u8*
222  format_bier_bift_id(u8 *s, va_list *ap)
223  {
224      bier_bift_id_t id = va_arg(*ap, bier_bift_id_t);
225      bier_table_sub_domain_id_t sd;
226      bier_table_set_id_t set;
227      bier_hdr_len_id_t bsl;
228
229      bier_bift_id_decode(id, &set, &sd, &bsl);
230
231      return (format(s, "0x%x -> set:%d sd:%d hdr-len:%U",
232                     id, set, sd, format_bier_hdr_len_id, bsl));
233  }