]>
Commit | Line | Data |
---|---|---|
212f5cbc | 1 | /* Ethernet-VPN Attribute handling file |
896014f4 DL |
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 | */ | |
212f5cbc PG |
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 | 37 | void 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 | 58 | int 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 | 80 | char *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 |
99 | char *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 |
109 | extern int |
110 | bgp_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 | } |