]> git.proxmox.com Git - mirror_frr.git/blob - bgpd/bgp_rd.c
zebra: Allow ns delete to happen after under/over flow checks
[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 #include "frrstr.h"
31
32 #include "bgpd/bgpd.h"
33 #include "bgpd/bgp_rd.h"
34 #include "bgpd/bgp_attr.h"
35
36 #if ENABLE_BGP_VNC
37 #include "bgpd/rfapi/rfapi_backend.h"
38 #endif
39
40 uint16_t decode_rd_type(uint8_t *pnt)
41 {
42 uint16_t v;
43
44 v = ((uint16_t)*pnt++ << 8);
45 #if ENABLE_BGP_VNC
46 /*
47 * VNC L2 stores LHI in lower byte, so omit it
48 */
49 if (v != RD_TYPE_VNC_ETH)
50 v |= (uint16_t)*pnt;
51 #else /* duplicate code for clarity */
52 v |= (uint16_t)*pnt;
53 #endif
54 return v;
55 }
56
57 void encode_rd_type(uint16_t v, uint8_t *pnt)
58 {
59 *((uint16_t *)pnt) = htons(v);
60 }
61
62 /* type == RD_TYPE_AS */
63 void decode_rd_as(uint8_t *pnt, struct rd_as *rd_as)
64 {
65 rd_as->as = (uint16_t)*pnt++ << 8;
66 rd_as->as |= (uint16_t)*pnt++;
67 ptr_get_be32(pnt, &rd_as->val);
68 }
69
70 /* type == RD_TYPE_AS4 */
71 void decode_rd_as4(uint8_t *pnt, struct rd_as *rd_as)
72 {
73 pnt = ptr_get_be32(pnt, &rd_as->as);
74 rd_as->val = ((uint16_t)*pnt++ << 8);
75 rd_as->val |= (uint16_t)*pnt;
76 }
77
78 /* type == RD_TYPE_IP */
79 void decode_rd_ip(uint8_t *pnt, struct rd_ip *rd_ip)
80 {
81 memcpy(&rd_ip->ip, pnt, 4);
82 pnt += 4;
83
84 rd_ip->val = ((uint16_t)*pnt++ << 8);
85 rd_ip->val |= (uint16_t)*pnt;
86 }
87
88 #if ENABLE_BGP_VNC
89 /* type == RD_TYPE_VNC_ETH */
90 void decode_rd_vnc_eth(uint8_t *pnt, struct rd_vnc_eth *rd_vnc_eth)
91 {
92 rd_vnc_eth->type = RD_TYPE_VNC_ETH;
93 rd_vnc_eth->local_nve_id = pnt[1];
94 memcpy(rd_vnc_eth->macaddr.octet, pnt + 2, ETH_ALEN);
95 }
96 #endif
97
98 int str2prefix_rd(const char *str, struct prefix_rd *prd)
99 {
100 int ret; /* ret of called functions */
101 int lret; /* local ret, of this func */
102 char *p;
103 char *p2;
104 struct stream *s = NULL;
105 char *half = NULL;
106 struct in_addr addr;
107
108 s = stream_new(8);
109
110 prd->family = AF_UNSPEC;
111 prd->prefixlen = 64;
112
113 lret = 0;
114 p = strchr(str, ':');
115 if (!p)
116 goto out;
117
118 if (!all_digit(p + 1))
119 goto out;
120
121 half = XMALLOC(MTYPE_TMP, (p - str) + 1);
122 memcpy(half, str, (p - str));
123 half[p - str] = '\0';
124
125 p2 = strchr(str, '.');
126
127 if (!p2) {
128 unsigned long as_val;
129
130 if (!all_digit(half))
131 goto out;
132
133 as_val = atol(half);
134 if (as_val > 0xffff) {
135 stream_putw(s, RD_TYPE_AS4);
136 stream_putl(s, as_val);
137 stream_putw(s, atol(p + 1));
138 } else {
139 stream_putw(s, RD_TYPE_AS);
140 stream_putw(s, as_val);
141 stream_putl(s, atol(p + 1));
142 }
143 } else {
144 ret = inet_aton(half, &addr);
145 if (!ret)
146 goto out;
147
148 stream_putw(s, RD_TYPE_IP);
149 stream_put_in_addr(s, &addr);
150 stream_putw(s, atol(p + 1));
151 }
152 memcpy(prd->val, s->data, 8);
153 lret = 1;
154
155 out:
156 if (s)
157 stream_free(s);
158 if (half)
159 XFREE(MTYPE_TMP, half);
160 return lret;
161 }
162
163 char *prefix_rd2str(struct prefix_rd *prd, char *buf, size_t size)
164 {
165 uint8_t *pnt;
166 uint16_t type;
167 struct rd_as rd_as;
168 struct rd_ip rd_ip;
169
170 assert(size >= RD_ADDRSTRLEN);
171
172 pnt = prd->val;
173
174 type = decode_rd_type(pnt);
175
176 if (type == RD_TYPE_AS) {
177 decode_rd_as(pnt + 2, &rd_as);
178 snprintf(buf, size, "%u:%d", rd_as.as, rd_as.val);
179 return buf;
180 } else if (type == RD_TYPE_AS4) {
181 decode_rd_as4(pnt + 2, &rd_as);
182 snprintf(buf, size, "%u:%d", rd_as.as, rd_as.val);
183 return buf;
184 } else if (type == RD_TYPE_IP) {
185 decode_rd_ip(pnt + 2, &rd_ip);
186 snprintf(buf, size, "%s:%d", inet_ntoa(rd_ip.ip), rd_ip.val);
187 return buf;
188 }
189 #if ENABLE_BGP_VNC
190 else if (type == RD_TYPE_VNC_ETH) {
191 snprintf(buf, size, "LHI:%d, %02x:%02x:%02x:%02x:%02x:%02x",
192 *(pnt + 1), /* LHI */
193 *(pnt + 2), /* MAC[0] */
194 *(pnt + 3), *(pnt + 4), *(pnt + 5), *(pnt + 6),
195 *(pnt + 7));
196
197 return buf;
198 }
199 #endif
200
201 snprintf(buf, size, "Unknown Type: %d", type);
202 return buf;
203 }
204
205 void form_auto_rd(struct in_addr router_id,
206 uint16_t rd_id,
207 struct prefix_rd *prd)
208 {
209 char buf[100];
210
211 prd->family = AF_UNSPEC;
212 prd->prefixlen = 64;
213 sprintf(buf, "%s:%hu", inet_ntoa(router_id), rd_id);
214 (void)str2prefix_rd(buf, prd);
215 }