]>
git.proxmox.com Git - mirror_frr.git/blob - bgpd/bgp_rd.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /* BGP RD definitions for BGP-based VPNs (IP/EVPN)
3 * -- brought over from bgpd/bgp_mplsvpn.c
4 * Copyright (C) 2000 Kunihiro Ishiguro <kunihiro@zebra.org>
16 #include "lib/printfrr.h"
18 #include "bgpd/bgpd.h"
19 #include "bgpd/bgp_rd.h"
20 #include "bgpd/bgp_attr.h"
23 #include "bgpd/rfapi/rfapi_backend.h"
26 uint16_t decode_rd_type(const uint8_t *pnt
)
30 v
= ((uint16_t)*pnt
++ << 8);
33 * VNC L2 stores LHI in lower byte, so omit it
35 if (v
!= RD_TYPE_VNC_ETH
)
37 #else /* duplicate code for clarity */
43 void encode_rd_type(uint16_t v
, uint8_t *pnt
)
45 *((uint16_t *)pnt
) = htons(v
);
48 /* type == RD_TYPE_AS */
49 void decode_rd_as(const uint8_t *pnt
, struct rd_as
*rd_as
)
51 rd_as
->as
= (uint16_t)*pnt
++ << 8;
52 rd_as
->as
|= (uint16_t)*pnt
++;
53 ptr_get_be32(pnt
, &rd_as
->val
);
56 /* type == RD_TYPE_AS4 */
57 void decode_rd_as4(const uint8_t *pnt
, struct rd_as
*rd_as
)
59 pnt
= ptr_get_be32(pnt
, &rd_as
->as
);
60 rd_as
->val
= ((uint16_t)*pnt
++ << 8);
61 rd_as
->val
|= (uint16_t)*pnt
;
64 /* type == RD_TYPE_IP */
65 void decode_rd_ip(const uint8_t *pnt
, struct rd_ip
*rd_ip
)
67 memcpy(&rd_ip
->ip
, pnt
, 4);
70 rd_ip
->val
= ((uint16_t)*pnt
++ << 8);
71 rd_ip
->val
|= (uint16_t)*pnt
;
75 /* type == RD_TYPE_VNC_ETH */
76 void decode_rd_vnc_eth(const uint8_t *pnt
, struct rd_vnc_eth
*rd_vnc_eth
)
78 rd_vnc_eth
->type
= RD_TYPE_VNC_ETH
;
79 rd_vnc_eth
->local_nve_id
= pnt
[1];
80 memcpy(rd_vnc_eth
->macaddr
.octet
, pnt
+ 2, ETH_ALEN
);
84 int str2prefix_rd(const char *str
, struct prefix_rd
*prd
)
89 struct stream
*s
= NULL
;
93 prd
->family
= AF_UNSPEC
;
100 if (!all_digit(p
+ 1))
103 s
= stream_new(RD_BYTES
);
105 half
= XMALLOC(MTYPE_TMP
, (p
- str
) + 1);
106 memcpy(half
, str
, (p
- str
));
107 half
[p
- str
] = '\0';
109 p2
= strchr(str
, '.');
112 unsigned long as_val
;
114 if (!all_digit(half
))
118 if (as_val
> 0xffff) {
119 stream_putw(s
, RD_TYPE_AS4
);
120 stream_putl(s
, as_val
);
121 stream_putw(s
, atol(p
+ 1));
123 stream_putw(s
, RD_TYPE_AS
);
124 stream_putw(s
, as_val
);
125 stream_putl(s
, atol(p
+ 1));
128 if (!inet_aton(half
, &addr
))
131 stream_putw(s
, RD_TYPE_IP
);
132 stream_put_in_addr(s
, &addr
);
133 stream_putw(s
, atol(p
+ 1));
135 memcpy(prd
->val
, s
->data
, 8);
141 XFREE(MTYPE_TMP
, half
);
145 char *prefix_rd2str(const struct prefix_rd
*prd
, char *buf
, size_t size
)
152 assert(size
>= RD_ADDRSTRLEN
);
156 type
= decode_rd_type(pnt
);
158 if (type
== RD_TYPE_AS
) {
159 decode_rd_as(pnt
+ 2, &rd_as
);
160 snprintf(buf
, size
, "%u:%u", rd_as
.as
, rd_as
.val
);
162 } else if (type
== RD_TYPE_AS4
) {
163 decode_rd_as4(pnt
+ 2, &rd_as
);
164 snprintf(buf
, size
, "%u:%u", rd_as
.as
, rd_as
.val
);
166 } else if (type
== RD_TYPE_IP
) {
167 decode_rd_ip(pnt
+ 2, &rd_ip
);
168 snprintfrr(buf
, size
, "%pI4:%hu", &rd_ip
.ip
, rd_ip
.val
);
171 #ifdef ENABLE_BGP_VNC
172 else if (type
== RD_TYPE_VNC_ETH
) {
173 snprintf(buf
, size
, "LHI:%d, %02x:%02x:%02x:%02x:%02x:%02x",
174 *(pnt
+ 1), /* LHI */
175 *(pnt
+ 2), /* MAC[0] */
176 *(pnt
+ 3), *(pnt
+ 4), *(pnt
+ 5), *(pnt
+ 6),
183 snprintf(buf
, size
, "Unknown Type: %d", type
);
187 void form_auto_rd(struct in_addr router_id
,
189 struct prefix_rd
*prd
)
193 prd
->family
= AF_UNSPEC
;
195 snprintfrr(buf
, sizeof(buf
), "%pI4:%hu", &router_id
, rd_id
);
196 (void)str2prefix_rd(buf
, prd
);
199 printfrr_ext_autoreg_p("RD", printfrr_prd
);
200 static ssize_t
printfrr_prd(struct fbuf
*buf
, struct printfrr_eargs
*ea
,
203 char rd_buf
[RD_ADDRSTRLEN
];
206 return bputs(buf
, "(null)");
208 prefix_rd2str(ptr
, rd_buf
, sizeof(rd_buf
));
210 return bputs(buf
, rd_buf
);