]> git.proxmox.com Git - mirror_frr.git/blame - bgpd/bgp_attr_evpn.c
Merge pull request #531 from qlyoung/fix-stack-ref
[mirror_frr.git] / bgpd / bgp_attr_evpn.c
CommitLineData
212f5cbc
PG
1/* Ethernet-VPN Attribute handling file
2 Copyright (C) 2016 6WIND
3
52884837 4This file is part of FRRouting.
212f5cbc 5
52884837 6FRRouting is free software; you can redistribute it and/or modify it
212f5cbc
PG
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
52884837 11FRRouting is distributed in the hope that it will be useful, but
212f5cbc
PG
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
52884837 17along with FRRouting; see the file COPYING. If not, write to the Free
212f5cbc
PG
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 34#include "bgpd/bgp_ecommunity.h"
3da6fcd5 35#include "bgpd/bgp_evpn.h"
dfa42ea3 36
31689a53 37void bgp_add_routermac_ecom(struct attr *attr, struct ethaddr *routermac)
dfa42ea3 38{
4d0e6ece 39 struct ecommunity_val routermac_ecom;
dfa42ea3 40
4d0e6ece
PG
41 if (attr->extra) {
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;
31689a53 45 memcpy(&routermac_ecom.val[2], routermac->octet, ETHER_ADDR_LEN);
4d0e6ece
PG
46 if (!attr->extra->ecommunity)
47 attr->extra->ecommunity = ecommunity_new();
48 ecommunity_add_val(attr->extra->ecommunity, &routermac_ecom);
9972b54e 49 ecommunity_str (attr->extra->ecommunity);
4d0e6ece 50 }
dfa42ea3 51}
212f5cbc 52
212f5cbc
PG
53/* converts to an esi
54 * returns 1 on success, 0 otherwise
55 * format accepted: AA:BB:CC:DD:EE:FF:GG:HH:II:JJ
56 * if id is null, check only is done
57 */
4d0e6ece 58int str2esi(const char *str, struct eth_segment_id *id)
212f5cbc 59{
20b80273
PG
60 unsigned int a[ESI_LEN];
61 int i;
212f5cbc 62
4d0e6ece
PG
63 if (!str)
64 return 0;
20b80273
PG
65 if (sscanf (str, "%2x:%2x:%2x:%2x:%2x:%2x:%2x:%2x:%2x:%2x",
66 a + 0, a + 1, a + 2, a + 3, a + 4, a + 5,
67 a + 6, a + 7, a + 8, a + 9) != ESI_LEN)
68 {
69 /* error in incoming str length */
70 return 0;
212f5cbc 71 }
20b80273
PG
72 /* valid mac address */
73 if (!id)
74 return 1;
75 for (i = 0; i < ESI_LEN; ++i)
76 id->val[i] = a[i] & 0xff;
4d0e6ece 77 return 1;
212f5cbc
PG
78}
79
4d0e6ece 80char *esi2str(struct eth_segment_id *id)
212f5cbc 81{
4d0e6ece
PG
82 char *ptr;
83 u_char *val;
212f5cbc 84
4d0e6ece
PG
85 if (!id)
86 return NULL;
212f5cbc 87
4d0e6ece 88 val = id->val;
ffd28f0e 89 ptr = (char *)XMALLOC(MTYPE_TMP, (ESI_LEN * 2 + ESI_LEN - 1 + 1) * sizeof(char));
212f5cbc 90
4d0e6ece
PG
91 snprintf(ptr, (ESI_LEN * 2 + ESI_LEN - 1 + 1),
92 "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x",
93 val[0], val[1], val[2], val[3], val[4],
94 val[5], val[6], val[7], val[8], val[9]);
212f5cbc 95
4d0e6ece 96 return ptr;
212f5cbc
PG
97}
98
212f5cbc
PG
99char *ecom_mac2str(char *ecom_mac)
100{
4d0e6ece 101 char *en;
212f5cbc 102
4d0e6ece
PG
103 en = ecom_mac;
104 en += 2;
31689a53 105 return prefix_mac2str((struct ethaddr *)en, NULL, 0);
212f5cbc 106}
3da6fcd5
PG
107
108/* dst prefix must be AF_INET or AF_INET6 prefix, to forge EVPN prefix */
4d0e6ece
PG
109extern int
110bgp_build_evpn_prefix(int evpn_type, uint32_t eth_tag, struct prefix *dst)
3da6fcd5 111{
4d0e6ece
PG
112 struct evpn_addr *p_evpn_p;
113 struct prefix p2;
114 struct prefix *src = &p2;
3da6fcd5 115
4d0e6ece
PG
116 if (!dst || dst->family == 0)
117 return -1;
118 /* store initial prefix in src */
119 prefix_copy(src, dst);
120 memset(dst, 0, sizeof(struct prefix));
121 p_evpn_p = &(dst->u.prefix_evpn);
122 dst->family = AF_ETHERNET;
123 p_evpn_p->route_type = evpn_type;
124 if (evpn_type == EVPN_IP_PREFIX) {
125 p_evpn_p->eth_tag = eth_tag;
126 p_evpn_p->ip_prefix_length = p2.prefixlen;
127 if (src->family == AF_INET) {
128 p_evpn_p->flags = IP_PREFIX_V4;
129 memcpy(&p_evpn_p->ip.v4_addr, &src->u.prefix4,
130 sizeof(struct in_addr));
131 dst->prefixlen = (u_char) PREFIX_LEN_ROUTE_TYPE_5_IPV4;
132 } else {
133 p_evpn_p->flags = IP_PREFIX_V6;
134 memcpy(&p_evpn_p->ip.v6_addr, &src->u.prefix6,
135 sizeof(struct in6_addr));
136 dst->prefixlen = (u_char) PREFIX_LEN_ROUTE_TYPE_5_IPV6;
137 }
138 } else
139 return -1;
140 return 0;
3da6fcd5 141}