Skip to content

Commit 1ef8aae

Browse files
committed
Add protocol dissector for BGP EVPN SAFI specified in RFC 7432
1 parent 14acf8e commit 1ef8aae

File tree

1 file changed

+179
-0
lines changed

1 file changed

+179
-0
lines changed

print-bgp.c

Lines changed: 179 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -893,6 +893,28 @@ bgp_vpn_rd_print(netdissect_options *ndo, const u_char *pptr)
893893
return (rd);
894894
}
895895

896+
/* Print an RFC 7432 Ethernet Segment Identifier */
897+
static const char *
898+
bgp_evpn_esi_print(netdissect_options *ndo, const u_char *pptr)
899+
{
900+
static char esi[sizeof("01:23:45:67:89:01:23:45:67:89")];
901+
902+
snprintf(esi, sizeof(esi),
903+
"%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x",
904+
GET_U_1(pptr),
905+
GET_U_1(pptr + 1),
906+
GET_U_1(pptr + 2),
907+
GET_U_1(pptr + 3),
908+
GET_U_1(pptr + 4),
909+
GET_U_1(pptr + 5),
910+
GET_U_1(pptr + 6),
911+
GET_U_1(pptr + 7),
912+
GET_U_1(pptr + 8),
913+
GET_U_1(pptr + 9));
914+
915+
return esi;
916+
}
917+
896918
/*
897919
* Print an RFC 4360 Extended Community.
898920
*/
@@ -1470,6 +1492,139 @@ print_labeled_vpn_l2(netdissect_options *ndo, const u_char *pptr)
14701492
return -2;
14711493
}
14721494

1495+
static int
1496+
print_evpn_prefix(netdissect_options *ndo, const u_char *pptr, u_int itemlen)
1497+
{
1498+
u_int ptype, plen, tlen, iplen, maclen;
1499+
1500+
if (itemlen < 2)
1501+
goto trunc;
1502+
1503+
ptype = GET_U_1(pptr);
1504+
plen = GET_U_1(pptr + 1);
1505+
tlen = plen + 2;
1506+
pptr += 2;
1507+
1508+
if (itemlen < tlen) {
1509+
ND_PRINT("\n\t (ran past the end)");
1510+
goto trunc;
1511+
}
1512+
1513+
ND_PRINT("\n\t EVPN Route-Type: %u", ptype);
1514+
1515+
switch (ptype) {
1516+
case 1: /* Ethernet auto-discovery route */
1517+
ND_PRINT("\n\t\tRD: %s", bgp_vpn_rd_print(ndo, pptr));
1518+
ND_PRINT("\n\t\tEthernet Segment ID: %s", bgp_evpn_esi_print(ndo, pptr + 8));
1519+
ND_PRINT("\n\t\tEthernet Tag: 0x%08x", GET_BE_U_4(pptr + 18));
1520+
ND_PRINT("\n\t\tMPLS Label: %u", GET_BE_U_3(pptr + 22));
1521+
break;
1522+
case 2: /* MAC/IP advertisement route */
1523+
ND_PRINT("\n\t\tRD: %s", bgp_vpn_rd_print(ndo, pptr));
1524+
ND_PRINT("\n\t\tEthernet Segment ID: %s", bgp_evpn_esi_print(ndo, pptr + 8));
1525+
ND_PRINT("\n\t\tEthernet Tag: 0x%08x", GET_BE_U_4(pptr + 18));
1526+
pptr += 22;
1527+
plen -= 22;
1528+
1529+
maclen = GET_U_1(pptr);
1530+
pptr++;
1531+
plen--;
1532+
1533+
ND_PRINT("\n\t\tMAC Address: ");
1534+
1535+
if ((plen * 8) < maclen) { /* maclen is in bits */
1536+
ND_PRINT("(ran past the end)");
1537+
break;
1538+
} else if (maclen == (sizeof(nd_mac48) * 8)) {
1539+
ND_PRINT("%s", GET_MAC48_STRING(pptr));
1540+
} else {
1541+
ND_PRINT("(illegal address length)");
1542+
}
1543+
1544+
pptr += maclen / 8;
1545+
plen -= maclen / 8;
1546+
1547+
iplen = GET_U_1(pptr);
1548+
pptr++;
1549+
plen--;
1550+
1551+
if (iplen != 0) {
1552+
ND_PRINT("\n\t\tIP Address: ");
1553+
1554+
if ((plen * 8) < iplen) { /* iplen is in bits */
1555+
ND_PRINT("(ran past the end)");
1556+
break;
1557+
} else if (iplen == (sizeof(nd_ipv4) * 8)) {
1558+
ND_PRINT("%s", GET_IPADDR_STRING(pptr));
1559+
} else if (iplen == (sizeof(nd_ipv6) * 8)) {
1560+
ND_PRINT("%s", GET_IP6ADDR_STRING(pptr));
1561+
} else {
1562+
ND_PRINT("(illegal address length)");
1563+
}
1564+
1565+
pptr += iplen / 8;
1566+
plen -= iplen / 8;
1567+
}
1568+
1569+
ND_PRINT("\n\t\tMPLS Label 1: %u", GET_BE_U_3(pptr));
1570+
pptr += 3;
1571+
plen -= 3;
1572+
1573+
if (plen > 0) {
1574+
ND_PRINT("\n\t\tMPLS Label 2: ");
1575+
1576+
if (plen < 3) {
1577+
ND_PRINT("(ran past the end)");
1578+
} else {
1579+
ND_PRINT("%u", GET_BE_U_3(pptr));
1580+
}
1581+
}
1582+
1583+
break;
1584+
case 3: /* Inclusive multicast ethernet tag route */
1585+
case 4: /* Ethernet segment route */
1586+
ND_PRINT("\n\t\tRD: %s", bgp_vpn_rd_print(ndo, pptr));
1587+
pptr += 8;
1588+
plen -= 8;
1589+
1590+
if (ptype == 3) {
1591+
ND_PRINT("\n\t\tEthernet Tag: 0x%08x", GET_BE_U_4(pptr));
1592+
pptr += 4;
1593+
plen -= 4;
1594+
} else if (ptype == 4) {
1595+
ND_PRINT("\n\t\tEthernet Segment ID: %s", bgp_evpn_esi_print(ndo, pptr));
1596+
pptr += 10;
1597+
plen -= 10;
1598+
}
1599+
1600+
iplen = GET_U_1(pptr);
1601+
pptr++;
1602+
plen--;
1603+
1604+
ND_PRINT("\n\t\tOriginating Router: ");
1605+
1606+
if ((plen * 8) < iplen) { /* iplen is in bits */
1607+
ND_PRINT("(ran past the end)");
1608+
} else if (iplen == (sizeof(nd_ipv4) * 8)) {
1609+
ND_PRINT("%s", GET_IPADDR_STRING(pptr));
1610+
} else if (iplen == (sizeof(nd_ipv6) * 8)) {
1611+
ND_PRINT("%s", GET_IP6ADDR_STRING(pptr));
1612+
} else {
1613+
ND_PRINT("(illegal address length)");
1614+
}
1615+
1616+
break;
1617+
default:
1618+
ND_PRINT(" (no decoder)");
1619+
break;
1620+
}
1621+
1622+
return tlen;
1623+
1624+
trunc:
1625+
return -2;
1626+
}
1627+
14731628
int
14741629
decode_prefix6(netdissect_options *ndo,
14751630
const u_char *pd, u_int itemlen, char *buf, size_t buflen)
@@ -1819,6 +1974,7 @@ bgp_mp_af_print(netdissect_options *ndo,
18191974
case (AFNUM_L2VPN<<8 | SAFNUM_VPNMULTICAST):
18201975
case (AFNUM_L2VPN<<8 | SAFNUM_VPNUNIMULTICAST):
18211976
case (AFNUM_VPLS<<8 | SAFNUM_VPLS):
1977+
case (AFNUM_VPLS<<8 | SAFNUM_EVPN):
18221978
break;
18231979
default:
18241980
ND_TCHECK_LEN(tptr, tlen);
@@ -1923,6 +2079,11 @@ bgp_nlri_print(netdissect_options *ndo, uint16_t af, uint8_t safi,
19232079
if (advance == -2)
19242080
goto trunc;
19252081
break;
2082+
case (AFNUM_VPLS<<8 | SAFNUM_EVPN):
2083+
advance = print_evpn_prefix(ndo, tptr, len);
2084+
if (advance == -2)
2085+
goto trunc;
2086+
break;
19262087
case (AFNUM_NSAP<<8 | SAFNUM_UNICAST):
19272088
case (AFNUM_NSAP<<8 | SAFNUM_MULTICAST):
19282089
case (AFNUM_NSAP<<8 | SAFNUM_UNIMULTICAST):
@@ -2250,6 +2411,24 @@ bgp_attr_print(netdissect_options *ndo,
22502411
tnhlen -= (sizeof(nd_ipv4));
22512412
}
22522413
break;
2414+
case (AFNUM_VPLS<<8 | SAFNUM_EVPN):
2415+
if (tnhlen < sizeof(nd_ipv4)) {
2416+
ND_PRINT("invalid len");
2417+
tptr += tnhlen;
2418+
tlen -= tnhlen;
2419+
tnhlen = 0;
2420+
} else if (tnhlen >= sizeof(nd_ipv6)) {
2421+
ND_PRINT("%s",GET_IP6ADDR_STRING(tptr));
2422+
tptr += sizeof(nd_ipv6);
2423+
tnhlen -= sizeof(nd_ipv6);
2424+
tlen -= sizeof(nd_ipv6);
2425+
} else {
2426+
ND_PRINT("%s",GET_IPADDR_STRING(tptr));
2427+
tptr += sizeof(nd_ipv4);
2428+
tnhlen -= sizeof(nd_ipv4);
2429+
tlen -= sizeof(nd_ipv4);
2430+
}
2431+
break;
22532432
case (AFNUM_NSAP<<8 | SAFNUM_UNICAST):
22542433
case (AFNUM_NSAP<<8 | SAFNUM_MULTICAST):
22552434
case (AFNUM_NSAP<<8 | SAFNUM_UNIMULTICAST):

0 commit comments

Comments
 (0)