]> git.proxmox.com Git - mirror_frr.git/blob - bgpd/bgp_rd.c
*: reindent
[mirror_frr.git] / bgpd / bgp_rd.c
1 /* BGP RD definitions for BGP-based VPNs (IP/EVPN)
2 * -- brought over from bgpd/bgp_mplsvpn.c
3 * Copyright (C) 2000 Kunihiro Ishiguro <kunihiro@zebra.org>
4 *
5 * This file is part of FRR.
6 *
7 * FRR is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2, or (at your option) any
10 * later version.
11 *
12 * FRR is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with FRR; see the file COPYING. If not, write to the Free
19 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
20 * 02111-1307, USA.
21 */
22
23 #include <zebra.h>
24 #include "command.h"
25 #include "log.h"
26 #include "prefix.h"
27 #include "memory.h"
28 #include "stream.h"
29 #include "filter.h"
30
31 #include "bgpd/bgpd.h"
32 #include "bgpd/bgp_rd.h"
33 #include "bgpd/bgp_attr.h"
34
35 #if ENABLE_BGP_VNC
36 #include "bgpd/rfapi/rfapi_backend.h"
37 #endif
38
39 u_int16_t decode_rd_type(u_char *pnt)
40 {
41 u_int16_t v;
42
43 v = ((u_int16_t)*pnt++ << 8);
44 #if ENABLE_BGP_VNC
45 /*
46 * VNC L2 stores LHI in lower byte, so omit it
47 */
48 if (v != RD_TYPE_VNC_ETH)
49 v |= (u_int16_t)*pnt;
50 #else /* duplicate code for clarity */
51 v |= (u_int16_t)*pnt;
52 #endif
53 return v;
54 }
55
56 void encode_rd_type(u_int16_t v, u_char *pnt)
57 {
58 *((u_int16_t *)pnt) = htons(v);
59 }
60
61 /* type == RD_TYPE_AS */
62 void decode_rd_as(u_char *pnt, struct rd_as *rd_as)
63 {
64 rd_as->as = (u_int16_t)*pnt++ << 8;
65 rd_as->as |= (u_int16_t)*pnt++;
66
67 rd_as->val = ((u_int32_t)*pnt++ << 24);
68 rd_as->val |= ((u_int32_t)*pnt++ << 16);
69 rd_as->val |= ((u_int32_t)*pnt++ << 8);
70 rd_as->val |= (u_int32_t)*pnt;
71 }
72
73 /* type == RD_TYPE_AS4 */
74 void decode_rd_as4(u_char *pnt, struct rd_as *rd_as)
75 {
76 rd_as->as = (u_int32_t)*pnt++ << 24;
77 rd_as->as |= (u_int32_t)*pnt++ << 16;
78 rd_as->as |= (u_int32_t)*pnt++ << 8;
79 rd_as->as |= (u_int32_t)*pnt++;
80
81 rd_as->val = ((u_int16_t)*pnt++ << 8);
82 rd_as->val |= (u_int16_t)*pnt;
83 }
84
85 /* type == RD_TYPE_IP */
86 void decode_rd_ip(u_char *pnt, struct rd_ip *rd_ip)
87 {
88 memcpy(&rd_ip->ip, pnt, 4);
89 pnt += 4;
90
91 rd_ip->val = ((u_int16_t)*pnt++ << 8);
92 rd_ip->val |= (u_int16_t)*pnt;
93 }
94
95 #if ENABLE_BGP_VNC
96 /* type == RD_TYPE_VNC_ETH */
97 void decode_rd_vnc_eth(u_char *pnt, struct rd_vnc_eth *rd_vnc_eth)
98 {
99 rd_vnc_eth->type = RD_TYPE_VNC_ETH;
100 rd_vnc_eth->local_nve_id = pnt[1];
101 memcpy(rd_vnc_eth->macaddr.octet, pnt + 2, ETHER_ADDR_LEN);
102 }
103 #endif
104
105 int str2prefix_rd(const char *str, struct prefix_rd *prd)
106 {
107 int ret; /* ret of called functions */
108 int lret; /* local ret, of this func */
109 char *p;
110 char *p2;
111 struct stream *s = NULL;
112 char *half = NULL;
113 struct in_addr addr;
114
115 s = stream_new(8);
116
117 prd->family = AF_UNSPEC;
118 prd->prefixlen = 64;
119
120 lret = 0;
121 p = strchr(str, ':');
122 if (!p)
123 goto out;
124
125 if (!all_digit(p + 1))
126 goto out;
127
128 half = XMALLOC(MTYPE_TMP, (p - str) + 1);
129 memcpy(half, str, (p - str));
130 half[p - str] = '\0';
131
132 p2 = strchr(str, '.');
133
134 if (!p2) {
135 unsigned long as_val;
136
137 if (!all_digit(half))
138 goto out;
139
140 as_val = atol(half);
141 if (as_val > 0xffff) {
142 stream_putw(s, RD_TYPE_AS4);
143 stream_putl(s, as_val);
144 stream_putw(s, atol(p + 1));
145 } else {
146 stream_putw(s, RD_TYPE_AS);
147 stream_putw(s, as_val);
148 stream_putl(s, atol(p + 1));
149 }
150 } else {
151 ret = inet_aton(half, &addr);
152 if (!ret)
153 goto out;
154
155 stream_putw(s, RD_TYPE_IP);
156 stream_put_in_addr(s, &addr);
157 stream_putw(s, atol(p + 1));
158 }
159 memcpy(prd->val, s->data, 8);
160 lret = 1;
161
162 out:
163 if (s)
164 stream_free(s);
165 if (half)
166 XFREE(MTYPE_TMP, half);
167 return lret;
168 }
169
170 char *prefix_rd2str(struct prefix_rd *prd, char *buf, size_t size)
171 {
172 u_char *pnt;
173 u_int16_t type;
174 struct rd_as rd_as;
175 struct rd_ip rd_ip;
176
177 if (size < RD_ADDRSTRLEN)
178 return NULL;
179
180 pnt = prd->val;
181
182 type = decode_rd_type(pnt);
183
184 if (type == RD_TYPE_AS) {
185 decode_rd_as(pnt + 2, &rd_as);
186 snprintf(buf, size, "%u:%d", rd_as.as, rd_as.val);
187 return buf;
188 } else if (type == RD_TYPE_AS4) {
189 decode_rd_as4(pnt + 2, &rd_as);
190 snprintf(buf, size, "%u:%d", rd_as.as, rd_as.val);
191 return buf;
192 } else if (type == RD_TYPE_IP) {
193 decode_rd_ip(pnt + 2, &rd_ip);
194 snprintf(buf, size, "%s:%d", inet_ntoa(rd_ip.ip), rd_ip.val);
195 return buf;
196 }
197 #if ENABLE_BGP_VNC
198 else if (type == RD_TYPE_VNC_ETH) {
199 snprintf(buf, size, "LHI:%d, %02x:%02x:%02x:%02x:%02x:%02x",
200 *(pnt + 1), /* LHI */
201 *(pnt + 2), /* MAC[0] */
202 *(pnt + 3), *(pnt + 4), *(pnt + 5), *(pnt + 6),
203 *(pnt + 7));
204
205 return buf;
206 }
207 #endif
208 return NULL;
209 }