]>
git.proxmox.com Git - mirror_frr.git/blob - 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>
5 * This file is part of FRR.
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
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.
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
32 #include "bgpd/bgpd.h"
33 #include "bgpd/bgp_rd.h"
34 #include "bgpd/bgp_attr.h"
37 #include "bgpd/rfapi/rfapi_backend.h"
40 uint16_t decode_rd_type(uint8_t *pnt
)
44 v
= ((uint16_t)*pnt
++ << 8);
47 * VNC L2 stores LHI in lower byte, so omit it
49 if (v
!= RD_TYPE_VNC_ETH
)
51 #else /* duplicate code for clarity */
57 void encode_rd_type(uint16_t v
, uint8_t *pnt
)
59 *((uint16_t *)pnt
) = htons(v
);
62 /* type == RD_TYPE_AS */
63 void decode_rd_as(uint8_t *pnt
, struct rd_as
*rd_as
)
65 rd_as
->as
= (uint16_t)*pnt
++ << 8;
66 rd_as
->as
|= (uint16_t)*pnt
++;
67 ptr_get_be32(pnt
, &rd_as
->val
);
70 /* type == RD_TYPE_AS4 */
71 void decode_rd_as4(uint8_t *pnt
, struct rd_as
*rd_as
)
73 pnt
= ptr_get_be32(pnt
, &rd_as
->as
);
74 rd_as
->val
= ((uint16_t)*pnt
++ << 8);
75 rd_as
->val
|= (uint16_t)*pnt
;
78 /* type == RD_TYPE_IP */
79 void decode_rd_ip(uint8_t *pnt
, struct rd_ip
*rd_ip
)
81 memcpy(&rd_ip
->ip
, pnt
, 4);
84 rd_ip
->val
= ((uint16_t)*pnt
++ << 8);
85 rd_ip
->val
|= (uint16_t)*pnt
;
89 /* type == RD_TYPE_VNC_ETH */
90 void decode_rd_vnc_eth(uint8_t *pnt
, struct rd_vnc_eth
*rd_vnc_eth
)
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
);
98 int str2prefix_rd(const char *str
, struct prefix_rd
*prd
)
100 int ret
; /* ret of called functions */
101 int lret
; /* local ret, of this func */
104 struct stream
*s
= NULL
;
110 prd
->family
= AF_UNSPEC
;
114 p
= strchr(str
, ':');
118 if (!all_digit(p
+ 1))
121 half
= XMALLOC(MTYPE_TMP
, (p
- str
) + 1);
122 memcpy(half
, str
, (p
- str
));
123 half
[p
- str
] = '\0';
125 p2
= strchr(str
, '.');
128 unsigned long as_val
;
130 if (!all_digit(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));
139 stream_putw(s
, RD_TYPE_AS
);
140 stream_putw(s
, as_val
);
141 stream_putl(s
, atol(p
+ 1));
144 ret
= inet_aton(half
, &addr
);
148 stream_putw(s
, RD_TYPE_IP
);
149 stream_put_in_addr(s
, &addr
);
150 stream_putw(s
, atol(p
+ 1));
152 memcpy(prd
->val
, s
->data
, 8);
159 XFREE(MTYPE_TMP
, half
);
163 char *prefix_rd2str(struct prefix_rd
*prd
, char *buf
, size_t size
)
170 assert(size
>= RD_ADDRSTRLEN
);
174 type
= decode_rd_type(pnt
);
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
);
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
);
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
);
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),
201 snprintf(buf
, size
, "Unknown Type: %d", type
);
205 void form_auto_rd(struct in_addr router_id
,
207 struct prefix_rd
*prd
)
211 prd
->family
= AF_UNSPEC
;
213 sprintf(buf
, "%s:%hu", inet_ntoa(router_id
), rd_id
);
214 (void)str2prefix_rd(buf
, prd
);