]> git.proxmox.com Git - mirror_frr.git/blob - bgpd/bgp_attr_evpn.c
Merge remote-tracking branch 'origin/stable/2.0'
[mirror_frr.git] / bgpd / bgp_attr_evpn.c
1 /* Ethernet-VPN Attribute handling file
2 * Copyright (C) 2016 6WIND
3 *
4 * This file is part of FRRouting.
5 *
6 * FRRouting is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2, or (at your option) any
9 * later version.
10 *
11 * FRRouting is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; see the file COPYING; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 #include <zebra.h>
22
23 #include "command.h"
24 #include "filter.h"
25 #include "prefix.h"
26 #include "log.h"
27 #include "memory.h"
28 #include "stream.h"
29
30 #include "bgpd/bgpd.h"
31 #include "bgpd/bgp_attr.h"
32 #include "bgpd/bgp_route.h"
33 #include "bgpd/bgp_attr_evpn.h"
34 #include "bgpd/bgp_ecommunity.h"
35 #include "bgpd/bgp_evpn.h"
36
37 void bgp_add_routermac_ecom(struct attr *attr, struct ethaddr *routermac)
38 {
39 struct ecommunity_val routermac_ecom;
40
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;
45 memcpy(&routermac_ecom.val[2], routermac->octet, ETHER_ADDR_LEN);
46 if (!attr->extra->ecommunity)
47 attr->extra->ecommunity = ecommunity_new();
48 ecommunity_add_val(attr->extra->ecommunity, &routermac_ecom);
49 ecommunity_str (attr->extra->ecommunity);
50 }
51 }
52
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 */
58 int str2esi(const char *str, struct eth_segment_id *id)
59 {
60 unsigned int a[ESI_LEN];
61 int i;
62
63 if (!str)
64 return 0;
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;
71 }
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;
77 return 1;
78 }
79
80 char *esi2str(struct eth_segment_id *id)
81 {
82 char *ptr;
83 u_char *val;
84
85 if (!id)
86 return NULL;
87
88 val = id->val;
89 ptr = (char *)XMALLOC(MTYPE_TMP, (ESI_LEN * 2 + ESI_LEN - 1 + 1) * sizeof(char));
90
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]);
95
96 return ptr;
97 }
98
99 char *ecom_mac2str(char *ecom_mac)
100 {
101 char *en;
102
103 en = ecom_mac;
104 en += 2;
105 return prefix_mac2str((struct ethaddr *)en, NULL, 0);
106 }
107
108 /* dst prefix must be AF_INET or AF_INET6 prefix, to forge EVPN prefix */
109 extern int
110 bgp_build_evpn_prefix(int evpn_type, uint32_t eth_tag, struct prefix *dst)
111 {
112 struct evpn_addr *p_evpn_p;
113 struct prefix p2;
114 struct prefix *src = &p2;
115
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;
141 }