]>
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
31 #include "bgpd/bgpd.h"
32 #include "bgpd/bgp_rd.h"
33 #include "bgpd/bgp_attr.h"
36 #include "bgpd/rfapi/rfapi_backend.h"
39 uint16_t decode_rd_type(uint8_t *pnt
)
43 v
= ((uint16_t)*pnt
++ << 8);
46 * VNC L2 stores LHI in lower byte, so omit it
48 if (v
!= RD_TYPE_VNC_ETH
)
50 #else /* duplicate code for clarity */
56 void encode_rd_type(uint16_t v
, uint8_t *pnt
)
58 *((uint16_t *)pnt
) = htons(v
);
61 /* type == RD_TYPE_AS */
62 void decode_rd_as(uint8_t *pnt
, struct rd_as
*rd_as
)
64 rd_as
->as
= (uint16_t)*pnt
++ << 8;
65 rd_as
->as
|= (uint16_t)*pnt
++;
66 ptr_get_be32(pnt
, &rd_as
->val
);
69 /* type == RD_TYPE_AS4 */
70 void decode_rd_as4(uint8_t *pnt
, struct rd_as
*rd_as
)
72 pnt
= ptr_get_be32(pnt
, &rd_as
->as
);
73 rd_as
->val
= ((uint16_t)*pnt
++ << 8);
74 rd_as
->val
|= (uint16_t)*pnt
;
77 /* type == RD_TYPE_IP */
78 void decode_rd_ip(uint8_t *pnt
, struct rd_ip
*rd_ip
)
80 memcpy(&rd_ip
->ip
, pnt
, 4);
83 rd_ip
->val
= ((uint16_t)*pnt
++ << 8);
84 rd_ip
->val
|= (uint16_t)*pnt
;
88 /* type == RD_TYPE_VNC_ETH */
89 void decode_rd_vnc_eth(uint8_t *pnt
, struct rd_vnc_eth
*rd_vnc_eth
)
91 rd_vnc_eth
->type
= RD_TYPE_VNC_ETH
;
92 rd_vnc_eth
->local_nve_id
= pnt
[1];
93 memcpy(rd_vnc_eth
->macaddr
.octet
, pnt
+ 2, ETH_ALEN
);
97 int str2prefix_rd(const char *str
, struct prefix_rd
*prd
)
99 int ret
; /* ret of called functions */
100 int lret
; /* local ret, of this func */
103 struct stream
*s
= NULL
;
109 prd
->family
= AF_UNSPEC
;
113 p
= strchr(str
, ':');
117 if (!all_digit(p
+ 1))
120 half
= XMALLOC(MTYPE_TMP
, (p
- str
) + 1);
121 memcpy(half
, str
, (p
- str
));
122 half
[p
- str
] = '\0';
124 p2
= strchr(str
, '.');
127 unsigned long as_val
;
129 if (!all_digit(half
))
133 if (as_val
> 0xffff) {
134 stream_putw(s
, RD_TYPE_AS4
);
135 stream_putl(s
, as_val
);
136 stream_putw(s
, atol(p
+ 1));
138 stream_putw(s
, RD_TYPE_AS
);
139 stream_putw(s
, as_val
);
140 stream_putl(s
, atol(p
+ 1));
143 ret
= inet_aton(half
, &addr
);
147 stream_putw(s
, RD_TYPE_IP
);
148 stream_put_in_addr(s
, &addr
);
149 stream_putw(s
, atol(p
+ 1));
151 memcpy(prd
->val
, s
->data
, 8);
158 XFREE(MTYPE_TMP
, half
);
162 char *prefix_rd2str(struct prefix_rd
*prd
, char *buf
, size_t size
)
169 assert(size
>= RD_ADDRSTRLEN
);
173 type
= decode_rd_type(pnt
);
175 if (type
== RD_TYPE_AS
) {
176 decode_rd_as(pnt
+ 2, &rd_as
);
177 snprintf(buf
, size
, "%u:%d", rd_as
.as
, rd_as
.val
);
179 } else if (type
== RD_TYPE_AS4
) {
180 decode_rd_as4(pnt
+ 2, &rd_as
);
181 snprintf(buf
, size
, "%u:%d", rd_as
.as
, rd_as
.val
);
183 } else if (type
== RD_TYPE_IP
) {
184 decode_rd_ip(pnt
+ 2, &rd_ip
);
185 snprintf(buf
, size
, "%s:%d", inet_ntoa(rd_ip
.ip
), rd_ip
.val
);
189 else if (type
== RD_TYPE_VNC_ETH
) {
190 snprintf(buf
, size
, "LHI:%d, %02x:%02x:%02x:%02x:%02x:%02x",
191 *(pnt
+ 1), /* LHI */
192 *(pnt
+ 2), /* MAC[0] */
193 *(pnt
+ 3), *(pnt
+ 4), *(pnt
+ 5), *(pnt
+ 6),
200 snprintf(buf
, size
, "Unknown Type: %d", type
);
204 void form_auto_rd(struct in_addr router_id
,
206 struct prefix_rd
*prd
)
210 prd
->family
= AF_UNSPEC
;
212 sprintf(buf
, "%s:%hu", inet_ntoa(router_id
), rd_id
);
213 (void)str2prefix_rd(buf
, prd
);