mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-05-28 22:01:07 +00:00
Merge pull request #2035 from vincentbernat/fix/no-etag-esi-ignore
bgpd: add basic support for ETI and ESI for BGP EVPN
This commit is contained in:
commit
e49b64dee7
@ -37,6 +37,7 @@
|
||||
unsigned long eth_tag_id;
|
||||
struct attr;
|
||||
|
||||
/* EVPN ESI */
|
||||
struct eth_segment_id {
|
||||
uint8_t val[ESI_LEN];
|
||||
};
|
||||
|
@ -2810,10 +2810,12 @@ static int process_type2_route(struct peer *peer, afi_t afi, safi_t safi,
|
||||
{
|
||||
struct prefix_rd prd;
|
||||
struct prefix_evpn p;
|
||||
struct bgp_route_evpn evpn;
|
||||
uint8_t ipaddr_len;
|
||||
uint8_t macaddr_len;
|
||||
mpls_label_t label[BGP_MAX_LABELS]; /* holds the VNI(s) as in packet */
|
||||
uint32_t num_labels = 0;
|
||||
uint32_t eth_tag;
|
||||
int ret;
|
||||
|
||||
/* Type-2 route should be either 33, 37 or 49 bytes or an
|
||||
@ -2829,6 +2831,8 @@ static int process_type2_route(struct peer *peer, afi_t afi, safi_t safi,
|
||||
return -1;
|
||||
}
|
||||
|
||||
memset(&evpn, 0, sizeof(evpn));
|
||||
|
||||
/* Make prefix_rd */
|
||||
prd.family = AF_UNSPEC;
|
||||
prd.prefixlen = 64;
|
||||
@ -2841,10 +2845,13 @@ static int process_type2_route(struct peer *peer, afi_t afi, safi_t safi,
|
||||
p.prefixlen = EVPN_TYPE_2_ROUTE_PREFIXLEN;
|
||||
p.prefix.route_type = BGP_EVPN_MAC_IP_ROUTE;
|
||||
|
||||
/* Skip over Ethernet Seg Identifier for now. */
|
||||
pfx += 10;
|
||||
/* Copy Ethernet Seg Identifier */
|
||||
memcpy(&evpn.eth_s_id.val, pfx, ESI_LEN);
|
||||
pfx += ESI_LEN;
|
||||
|
||||
/* Skip over Ethernet Tag for now. */
|
||||
/* Copy Ethernet Tag */
|
||||
memcpy(ð_tag, pfx, 4);
|
||||
p.prefix.eth_tag = ntohl(eth_tag);
|
||||
pfx += 4;
|
||||
|
||||
/* Get the MAC Addr len */
|
||||
@ -2902,11 +2909,11 @@ static int process_type2_route(struct peer *peer, afi_t afi, safi_t safi,
|
||||
if (attr)
|
||||
ret = bgp_update(peer, (struct prefix *)&p, addpath_id, attr,
|
||||
afi, safi, ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL,
|
||||
&prd, &label[0], num_labels, 0, NULL);
|
||||
&prd, &label[0], num_labels, 0, &evpn);
|
||||
else
|
||||
ret = bgp_withdraw(peer, (struct prefix *)&p, addpath_id, attr,
|
||||
afi, safi, ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL,
|
||||
&prd, &label[0], num_labels, NULL);
|
||||
&prd, &label[0], num_labels, &evpn);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -2920,6 +2927,7 @@ static int process_type3_route(struct peer *peer, afi_t afi, safi_t safi,
|
||||
struct prefix_rd prd;
|
||||
struct prefix_evpn p;
|
||||
uint8_t ipaddr_len;
|
||||
uint32_t eth_tag;
|
||||
int ret;
|
||||
|
||||
/* Type-3 route should be either 17 or 29 bytes: RD (8), Eth Tag (4),
|
||||
@ -2956,7 +2964,9 @@ static int process_type3_route(struct peer *peer, afi_t afi, safi_t safi,
|
||||
p.prefixlen = EVPN_TYPE_3_ROUTE_PREFIXLEN;
|
||||
p.prefix.route_type = BGP_EVPN_IMET_ROUTE;
|
||||
|
||||
/* Skip over Ethernet Tag for now. */
|
||||
/* Copy Ethernet Tag */
|
||||
memcpy(ð_tag, pfx, 4);
|
||||
p.prefix.eth_tag = ntohl(eth_tag);
|
||||
pfx += 4;
|
||||
|
||||
/* Get the IP. */
|
||||
@ -3574,7 +3584,7 @@ void bgp_evpn_route2json(struct prefix_evpn *p, json_object *json)
|
||||
|
||||
if (p->prefix.route_type == BGP_EVPN_IMET_ROUTE) {
|
||||
json_object_int_add(json, "routeType", p->prefix.route_type);
|
||||
json_object_int_add(json, "ethTag", 0);
|
||||
json_object_int_add(json, "ethTag", p->prefix.eth_tag);
|
||||
json_object_int_add(json, "ipLen",
|
||||
IS_EVPN_PREFIX_IPADDR_V4(p)
|
||||
? IPV4_MAX_BITLEN
|
||||
@ -3585,10 +3595,7 @@ void bgp_evpn_route2json(struct prefix_evpn *p, json_object *json)
|
||||
if (IS_EVPN_PREFIX_IPADDR_NONE(p)) {
|
||||
json_object_int_add(json, "routeType",
|
||||
p->prefix.route_type);
|
||||
json_object_int_add(
|
||||
json, "esi",
|
||||
0); /* TODO: we don't support esi yet */
|
||||
json_object_int_add(json, "ethTag", 0);
|
||||
json_object_int_add(json, "ethTag", p->prefix.eth_tag);
|
||||
json_object_int_add(json, "macLen", 8 * ETH_ALEN);
|
||||
json_object_string_add(json, "mac",
|
||||
prefix_mac2str(&p->prefix.mac,
|
||||
@ -3602,10 +3609,7 @@ void bgp_evpn_route2json(struct prefix_evpn *p, json_object *json)
|
||||
|
||||
json_object_int_add(json, "routeType",
|
||||
p->prefix.route_type);
|
||||
json_object_int_add(
|
||||
json, "esi",
|
||||
0); /* TODO: we don't support esi yet */
|
||||
json_object_int_add(json, "ethTag", 0);
|
||||
json_object_int_add(json, "ethTag", p->prefix.eth_tag);
|
||||
json_object_int_add(json, "macLen", 8 * ETH_ALEN);
|
||||
json_object_string_add(json, "mac",
|
||||
prefix_mac2str(&p->prefix.mac,
|
||||
@ -3635,14 +3639,17 @@ char *bgp_evpn_route2str(struct prefix_evpn *p, char *buf, int len)
|
||||
char buf2[PREFIX2STR_BUFFER];
|
||||
|
||||
if (p->prefix.route_type == BGP_EVPN_IMET_ROUTE) {
|
||||
snprintf(buf, len, "[%d]:[0]:[%d]:[%s]", p->prefix.route_type,
|
||||
snprintf(buf, len, "[%d]:[%d]:[%d]:[%s]", p->prefix.route_type,
|
||||
p->prefix.eth_tag,
|
||||
IS_EVPN_PREFIX_IPADDR_V4(p) ? IPV4_MAX_BITLEN
|
||||
: IPV6_MAX_BITLEN,
|
||||
inet_ntoa(p->prefix.ip.ipaddr_v4));
|
||||
} else if (p->prefix.route_type == BGP_EVPN_MAC_IP_ROUTE) {
|
||||
if (IS_EVPN_PREFIX_IPADDR_NONE(p))
|
||||
snprintf(buf, len, "[%d]:[0]:[0]:[%d]:[%s]",
|
||||
p->prefix.route_type, 8 * ETH_ALEN,
|
||||
snprintf(buf, len, "[%d]:[%d]:[%d]:[%s]",
|
||||
p->prefix.route_type,
|
||||
p->prefix.eth_tag,
|
||||
8 * ETH_ALEN,
|
||||
prefix_mac2str(&p->prefix.mac, buf1,
|
||||
sizeof(buf1)));
|
||||
else {
|
||||
@ -3650,8 +3657,10 @@ char *bgp_evpn_route2str(struct prefix_evpn *p, char *buf, int len)
|
||||
|
||||
family = IS_EVPN_PREFIX_IPADDR_V4(p) ? AF_INET
|
||||
: AF_INET6;
|
||||
snprintf(buf, len, "[%d]:[0]:[0]:[%d]:[%s]:[%d]:[%s]",
|
||||
p->prefix.route_type, 8 * ETH_ALEN,
|
||||
snprintf(buf, len, "[%d]:[%d]:[%d]:[%s]:[%d]:[%s]",
|
||||
p->prefix.route_type,
|
||||
p->prefix.eth_tag,
|
||||
8 * ETH_ALEN,
|
||||
prefix_mac2str(&p->prefix.mac, buf1,
|
||||
sizeof(buf1)),
|
||||
family == AF_INET ? IPV4_MAX_BITLEN
|
||||
@ -3660,8 +3669,10 @@ char *bgp_evpn_route2str(struct prefix_evpn *p, char *buf, int len)
|
||||
PREFIX2STR_BUFFER));
|
||||
}
|
||||
} else if (p->prefix.route_type == BGP_EVPN_IP_PREFIX_ROUTE) {
|
||||
snprintf(buf, len, "[%d]:[0]:[0]:[%d]:[%s]",
|
||||
p->prefix.route_type, p->prefix.ip_prefix_length,
|
||||
snprintf(buf, len, "[%d]:[%d]:[%d]:[%s]",
|
||||
p->prefix.route_type,
|
||||
p->prefix.eth_tag,
|
||||
p->prefix.ip_prefix_length,
|
||||
IS_EVPN_PREFIX_IPADDR_V4(p)
|
||||
? inet_ntoa(p->prefix.ip.ipaddr_v4)
|
||||
: inet6_ntoa(p->prefix.ip.ipaddr_v6));
|
||||
@ -3703,8 +3714,11 @@ void bgp_evpn_encode_prefix(struct stream *s, struct prefix *p,
|
||||
len += 3;
|
||||
stream_putc(s, len);
|
||||
stream_put(s, prd->val, 8); /* RD */
|
||||
stream_put(s, 0, 10); /* ESI */
|
||||
stream_putl(s, 0); /* Ethernet Tag ID */
|
||||
if (attr)
|
||||
stream_put(s, &attr->evpn_overlay.eth_s_id, ESI_LEN);
|
||||
else
|
||||
stream_put(s, 0, 10);
|
||||
stream_putl(s, evp->prefix.eth_tag); /* Ethernet Tag ID */
|
||||
stream_putc(s, 8 * ETH_ALEN); /* Mac Addr Len - bits */
|
||||
stream_put(s, evp->prefix.mac.octet, 6); /* Mac Addr */
|
||||
stream_putc(s, 8 * ipa_len); /* IP address Length */
|
||||
@ -3720,7 +3734,7 @@ void bgp_evpn_encode_prefix(struct stream *s, struct prefix *p,
|
||||
case BGP_EVPN_IMET_ROUTE:
|
||||
stream_putc(s, 17); // TODO: length - assumes IPv4 address
|
||||
stream_put(s, prd->val, 8); /* RD */
|
||||
stream_putl(s, 0); /* Ethernet Tag ID */
|
||||
stream_putl(s, evp->prefix.eth_tag); /* Ethernet Tag ID */
|
||||
stream_putc(s, IPV4_MAX_BITLEN); /* IP address Length - bits */
|
||||
/* Originating Router's IP Addr */
|
||||
stream_put_in_addr(s, &evp->prefix.ip.ipaddr_v4);
|
||||
|
@ -327,9 +327,9 @@ static void bgp_evpn_show_route_header(struct vty *vty, struct bgp *bgp,
|
||||
"* valid, > best, i - internal\n");
|
||||
vty_out(vty, "Origin codes: i - IGP, e - EGP, ? - incomplete\n");
|
||||
vty_out(vty,
|
||||
"EVPN type-2 prefix: [2]:[ESI]:[EthTag]:[MAClen]:[MAC]:[IPlen]:[IP]\n");
|
||||
"EVPN type-2 prefix: [2]:[EthTag]:[MAClen]:[MAC]:[IPlen]:[IP]\n");
|
||||
vty_out(vty, "EVPN type-3 prefix: [3]:[EthTag]:[IPlen]:[OrigIP]\n");
|
||||
vty_out(vty, "EVPN type-5 prefix: [5]:[ESI]:[EthTag]:[IPlen]:[IP]\n\n");
|
||||
vty_out(vty, "EVPN type-5 prefix: [5]:[EthTag]:[IPlen]:[IP]\n\n");
|
||||
vty_out(vty, "%s", ri_header);
|
||||
}
|
||||
|
||||
@ -2110,11 +2110,11 @@ static void evpn_show_route_rd(struct vty *vty, struct bgp *bgp,
|
||||
/* RD header and legend - once overall. */
|
||||
if (rd_header && !json) {
|
||||
vty_out(vty,
|
||||
"EVPN type-2 prefix: [2]:[ESI]:[EthTag]:[MAClen]:[MAC]\n");
|
||||
"EVPN type-2 prefix: [2]:[EthTag]:[MAClen]:[MAC]\n");
|
||||
vty_out(vty,
|
||||
"EVPN type-3 prefix: [3]:[EthTag]:[IPlen]:[OrigIP]\n");
|
||||
vty_out(vty,
|
||||
"EVPN type-5 prefix: [5]:[ESI]:[EthTag]:[IPlen]:[IP]\n\n");
|
||||
"EVPN type-5 prefix: [5]:[EthTag]:[IPlen]:[IP]\n\n");
|
||||
rd_header = 0;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user