]> git.proxmox.com Git - mirror_frr.git/blame - bgpd/bgp_attr_evpn.c
bgpd: vty commands added for EVPN address family
[mirror_frr.git] / bgpd / bgp_attr_evpn.c
CommitLineData
212f5cbc
PG
1/* Ethernet-VPN Attribute handling file
2 Copyright (C) 2016 6WIND
3
4This file is part of Free Range Routing.
5
6Free Range Routing is free software; you can redistribute it and/or modify it
7under the terms of the GNU General Public License as published by the
8Free Software Foundation; either version 2, or (at your option) any
9later version.
10
11Free Range Routing is distributed in the hope that it will be useful, but
12WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with Free Range Routing; see the file COPYING. If not, write to the Free
18Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
1902111-1307, USA. */
20
21#include <zebra.h>
22
23#include "command.h"
7ef5a232 24#include "filter.h"
212f5cbc
PG
25#include "prefix.h"
26#include "log.h"
27#include "memory.h"
28#include "stream.h"
29
dfa42ea3
PG
30#include "bgpd/bgpd.h"
31#include "bgpd/bgp_attr.h"
32#include "bgpd/bgp_route.h"
212f5cbc 33#include "bgpd/bgp_attr_evpn.h"
dfa42ea3
PG
34#include "bgpd/bgp_ecommunity.h"
35
36void bgp_add_routermac_ecom (struct attr* attr, char * routermac)
37{
38 struct ecommunity_val routermac_ecom;
39
40 if(attr->extra)
41 {
42 memset(&routermac_ecom, 0, sizeof(struct ecommunity_val));
43 routermac_ecom.val[0] = ECOMMUNITY_ENCODE_EVPN;
44 routermac_ecom.val[1] = ECOMMUNITY_EVPN_SUBTYPE_ROUTERMAC;
45 memcpy(&routermac_ecom.val[2], routermac, MAC_LEN);
46 if(!attr->extra->ecommunity)
47 attr->extra->ecommunity = ecommunity_new ();
48 ecommunity_add_val(attr->extra->ecommunity, &routermac_ecom);
49 }
50}
212f5cbc
PG
51
52static uint8_t convertchartohexa (uint8_t *hexa, int *error)
53{
54 if( (*hexa == '0') || (*hexa == '1') || (*hexa == '2') ||
55 (*hexa == '3') || (*hexa == '4') || (*hexa == '5') ||
56 (*hexa == '6') || (*hexa == '7') || (*hexa == '8') ||
57 (*hexa == '9'))
58 return (uint8_t)(*hexa)-'0';
59 if((*hexa == 'a') || (*hexa == 'A'))
60 return 0xa;
61 if((*hexa == 'b') || (*hexa == 'B'))
62 return 0xb;
63 if((*hexa == 'c') || (*hexa == 'C'))
64 return 0xc;
65 if((*hexa == 'd') || (*hexa == 'D'))
66 return 0xd;
67 if((*hexa == 'e') || (*hexa == 'E'))
68 return 0xe;
69 if((*hexa == 'f') || (*hexa == 'F'))
70 return 0xf;
71 *error = -1;
72 return 0;
73}
74
75/* converts to internal representation of mac address
76 * returns 1 on success, 0 otherwise
77 * format accepted: AA:BB:CC:DD:EE:FF
78 * if mac parameter is null, then check only
79 */
80int
81str2mac (const char *str, char *mac)
82{
83 unsigned int k=0, i, j;
84 uint8_t *ptr, *ptr2;
85 size_t len;
86 uint8_t car;
87
88 if (!str)
89 return 0;
90
91 if (str[0] == ':' && str[1] == '\0')
92 return 1;
93
94 i = 0;
95 ptr = (uint8_t *)str;
96 while (i < 6)
97 {
98 uint8_t temp[5];
99 int error = 0;
100 ptr2 = (uint8_t *)strchr((const char *)ptr, ':');
101 if (ptr2 == NULL)
102 {
103 /* if last occurence return ok */
104 if(i != 5)
105 {
106 zlog_err("[%s]: format non recognized",mac);
107 return 0;
108 }
109 len = strlen((char *)ptr);
110 }
111 else
112 {
113 len = ptr2 - ptr;
114 }
115 if(len > 5)
116 {
117 zlog_err("[%s]: format non recognized",mac);
118 return 0;
119 }
120 memcpy(temp, ptr, len);
121 for(j=0;j< len;j++)
122 {
123 if (k >= MAC_LEN)
124 return 0;
125 if(mac)
126 mac[k] = 0;
127 car = convertchartohexa (&temp[j], &error);
128 if (error)
129 return 0;
130 if(mac)
131 mac[k] = car << 4;
132 j++;
133 if(j == len)
134 return 0;
135 car = convertchartohexa (&temp[j], &error) & 0xf;
136 if (error)
137 return 0;
138 if(mac)
139 mac[k] |= car & 0xf;
140 k++;
141 i++;
142 }
143 ptr = ptr2;
144 if(ptr == NULL)
145 break;
146 ptr++;
147 }
148 if(mac && 0)
149 {
150 zlog_err("leave correct : %02x:%02x:%02x:%02x:%02x:%02x",
151 mac[0] & 0xff, mac[1] & 0xff, mac[2] & 0xff,
152 mac[3] & 0xff, mac[4] & 0xff, mac[5] & 0xff);
153 }
154 return 1;
155}
156
157/* converts to an esi
158 * returns 1 on success, 0 otherwise
159 * format accepted: AA:BB:CC:DD:EE:FF:GG:HH:II:JJ
160 * if id is null, check only is done
161 */
162int
163str2esi (const char *str, struct eth_segment_id *id)
164{
165 unsigned int k=0, i, j;
166 uint8_t *ptr, *ptr2;
167 size_t len;
168 uint8_t car;
169
170 if (!str)
171 return 0;
172 if (str[0] == ':' && str[1] == '\0')
173 return 1;
174
175 i = 0;
176 ptr = (uint8_t *)str;
177 while (i < 10)
178 {
179 uint8_t temp[5];
180 int error = 0;
181 ptr2 = (uint8_t *)strchr((const char *)ptr, ':');
182 if (ptr2 == NULL)
183 {
184 /* if last occurence return ok */
185 if(i != 9)
186 {
187 zlog_err("[%s]: format non recognized",str);
188 return 0;
189 }
190 len = strlen((char *)ptr);
191 }
192 else
193 {
194 len = ptr2 - ptr;
195 }
196 memcpy(temp, ptr, len);
197 if(len > 5)
198 {
199 zlog_err("[%s]: format non recognized",str);
200 return 0;
201 }
202 for(j=0;j< len;j++)
203 {
204 if (k >= ESI_LEN)
205 return 0;
206 if(id)
207 id->val[k] = 0;
208 car = convertchartohexa (&temp[j], &error);
209 if (error)
210 return 0;
211 if(id)
212 id->val[k] = car << 4;
213 j++;
214 if(j == len)
215 return 0;
216 car = convertchartohexa (&temp[j], &error) & 0xf;
217 if (error)
218 return 0;
219 if(id)
220 id->val[k] |= car & 0xf;
221 k++;
222 i++;
223 }
224 ptr = ptr2;
225 if(ptr == NULL)
226 break;
227 ptr++;
228 }
229 if(id && 0)
230 {
231 zlog_err("leave correct : %02x:%02x:%02x:%02x:%02x",
232 id->val[0], id->val[1], id->val[2], id->val[3], id->val[4]);
233 zlog_err("%02x:%02x:%02x:%02x:%02x",
234 id->val[5], id->val[6], id->val[7], id->val[8], id->val[9]);
235 }
236 return 1;
237}
238
239char *
240esi2str (struct eth_segment_id *id)
241{
242 char *ptr;
243 u_char *val;
244
245 if(!id)
246 return NULL;
247
248 val = id->val;
249 ptr = (char *) malloc ((ESI_LEN*2+ESI_LEN-1+1)*sizeof(char));
250
251 snprintf (ptr, (ESI_LEN*2+ESI_LEN-1+1),
252 "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x",
253 val[0], val[1], val[2], val[3], val[4],
254 val[5], val[6], val[7], val[8], val[9]);
255
256 return ptr;
257}
258
259char *
260mac2str (char *mac)
261{
262 char *ptr;
263
264 if(!mac)
265 return NULL;
266
267 ptr = (char *) malloc ((MAC_LEN*2+MAC_LEN-1+1)*sizeof(char));
268
269 snprintf (ptr, (MAC_LEN*2+MAC_LEN-1+1), "%02x:%02x:%02x:%02x:%02x:%02x",
270 (uint8_t) mac[0], (uint8_t)mac[1], (uint8_t)mac[2], (uint8_t)mac[3],
271 (uint8_t)mac[4], (uint8_t)mac[5]);
272
273 return ptr;
274}
275
276char *ecom_mac2str(char *ecom_mac)
277{
278 char *en;
279
280 en = ecom_mac;
281 en+=2;
282 return mac2str(en);
283}