From 9cabb64b320a946b401daa3f6ee7adcefe1548b6 Mon Sep 17 00:00:00 2001 From: vivek Date: Wed, 15 Jun 2016 10:25:35 -0700 Subject: [PATCH] Quagga: AFI/SAFI mappings IANA to/from internal values Introduce internal and IANA defintions for AFI/SAFI and mapping functions and modify code to use these. This refactoring will facilitate adding support for other AFI/SAFI whose IANA values won't be suitable for internal data structure definitions (e.g., they are not contiguous). The commit adds some fixes related to afi/safi testing with 'make check ' command. Signed-off-by: Vivek Venkatraman Reviewed-by: Donald Sharp Signed-off-by: Philippe Guibert Ticket: CM-11416 Reviewed By: CCR-3594 (mpls branch) Testing Done: Not tested now, tested earlier on mpls branch --- bgpd/bgp_attr.c | 62 ++++++-- bgpd/bgp_open.c | 273 +++++++++++++----------------------- bgpd/bgp_open.h | 1 - bgpd/bgp_packet.c | 101 ++++++------- bgpd/bgp_route.c | 15 +- bgpd/bgpd.c | 29 ++++ bgpd/bgpd.h | 11 +- bgpd/rfapi/rfapi_import.c | 5 +- lib/zebra.h | 67 ++++++++- tests/bgp_capability_test.c | 30 ++-- tests/bgp_mp_attr_test.c | 68 +++++---- 11 files changed, 347 insertions(+), 315 deletions(-) diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c index 534a0323c4..9e0212b74c 100644 --- a/bgpd/bgp_attr.c +++ b/bgpd/bgp_attr.c @@ -1857,8 +1857,8 @@ int bgp_mp_reach_parse (struct bgp_attr_parser_args *args, struct bgp_nlri *mp_update) { - afi_t afi; - safi_t safi; + afi_t pkt_afi, afi; + safi_t pkt_safi, safi; bgp_size_t nlri_len; size_t start; struct stream *s; @@ -1882,8 +1882,20 @@ bgp_mp_reach_parse (struct bgp_attr_parser_args *args, } /* Load AFI, SAFI. */ - afi = stream_getw (s); - safi = stream_getc (s); + pkt_afi = stream_getw (s); + pkt_safi = stream_getc (s); + + /* Convert AFI, SAFI to internal values, check. */ + if (bgp_map_afi_safi_iana2int (pkt_afi, pkt_safi, &afi, &safi)) + { + /* Log if AFI or SAFI is unrecognized. This is not an error unless + * the attribute is otherwise malformed. + */ + if (bgp_debug_update(peer, NULL, NULL, 0)) + zlog_debug ("%s: MP_REACH received AFI %u or SAFI %u is unrecognized", + peer->host, pkt_afi, pkt_safi); + return BGP_ATTR_PARSE_ERROR; + } /* Get nexthop length. */ attre->mp_nexthop_len = stream_getc (s); @@ -1998,8 +2010,8 @@ bgp_mp_unreach_parse (struct bgp_attr_parser_args *args, struct bgp_nlri *mp_withdraw) { struct stream *s; - afi_t afi; - safi_t safi; + afi_t pkt_afi, afi; + safi_t pkt_safi, safi; u_int16_t withdraw_len; struct peer *const peer = args->peer; struct attr *const attr = args->attr; @@ -2011,9 +2023,21 @@ bgp_mp_unreach_parse (struct bgp_attr_parser_args *args, if ((length > STREAM_READABLE(s)) || (length < BGP_MP_UNREACH_MIN_SIZE)) return BGP_ATTR_PARSE_ERROR_NOTIFYPLS; - afi = stream_getw (s); - safi = stream_getc (s); - + pkt_afi = stream_getw (s); + pkt_safi = stream_getc (s); + + /* Convert AFI, SAFI to internal values, check. */ + if (bgp_map_afi_safi_iana2int (pkt_afi, pkt_safi, &afi, &safi)) + { + /* Log if AFI or SAFI is unrecognized. This is not an error unless + * the attribute is otherwise malformed. + */ + if (bgp_debug_update(peer, NULL, NULL, 0)) + zlog_debug ("%s: MP_UNREACH received AFI %u or SAFI %u is unrecognized", + peer->host, pkt_afi, pkt_safi); + return BGP_ATTR_PARSE_ERROR; + } + withdraw_len = length - BGP_MP_UNREACH_MIN_SIZE; mp_withdraw->afi = afi; @@ -2634,6 +2658,8 @@ bgp_packet_mpattr_start (struct stream *s, afi_t afi, safi_t safi, afi_t nh_afi, struct attr *attr) { size_t sizep; + afi_t pkt_afi; + safi_t pkt_safi; /* Set extended bit always to encode the attribute length as 2 bytes */ stream_putc (s, BGP_ATTR_FLAG_OPTIONAL|BGP_ATTR_FLAG_EXTLEN); @@ -2641,8 +2667,12 @@ bgp_packet_mpattr_start (struct stream *s, afi_t afi, safi_t safi, afi_t nh_afi, sizep = stream_get_endp (s); stream_putw (s, 0); /* Marker: Attribute length. */ - stream_putw (s, afi); - stream_putc (s, (safi == SAFI_MPLS_VPN) ? SAFI_MPLS_LABELED_VPN : safi); + + /* Convert AFI, SAFI to values for packet. */ + bgp_map_afi_safi_int2iana (afi, safi, &pkt_afi, &pkt_safi); + + stream_putw (s, pkt_afi); /* AFI */ + stream_putc (s, pkt_safi); /* SAFI */ /* Nexthop */ switch (nh_afi) @@ -3261,6 +3291,8 @@ size_t bgp_packet_mpunreach_start (struct stream *s, afi_t afi, safi_t safi) { unsigned long attrlen_pnt; + afi_t pkt_afi; + safi_t pkt_safi; /* Set extended bit always to encode the attribute length as 2 bytes */ stream_putc (s, BGP_ATTR_FLAG_OPTIONAL|BGP_ATTR_FLAG_EXTLEN); @@ -3269,8 +3301,12 @@ bgp_packet_mpunreach_start (struct stream *s, afi_t afi, safi_t safi) attrlen_pnt = stream_get_endp (s); stream_putw (s, 0); /* Length of this attribute. */ - stream_putw (s, afi); - stream_putc (s, (safi == SAFI_MPLS_VPN) ? SAFI_MPLS_LABELED_VPN : safi); + /* Convert AFI, SAFI to values for packet. */ + bgp_map_afi_safi_int2iana (afi, safi, &pkt_afi, &pkt_safi); + + stream_putw (s, pkt_afi); + stream_putc (s, pkt_safi); + return attrlen_pnt; } diff --git a/bgpd/bgp_open.c b/bgpd/bgp_open.c index af3c0486e5..4a06881041 100644 --- a/bgpd/bgp_open.c +++ b/bgpd/bgp_open.c @@ -79,9 +79,13 @@ bgp_capability_vty_out (struct vty *vty, struct peer *peer, u_char use_json, jso if (hdr->code == CAPABILITY_CODE_MP) { + afi_t afi; + safi_t safi; + + bgp_map_afi_safi_iana2int (ntohs(mpc.afi), mpc.safi, &afi, &safi); if (use_json) { - switch (ntohs (mpc.afi)) + switch (afi) { case AFI_IP: json_object_string_add(json_cap, "capabilityErrorMultiProtocolAfi", "IPv4"); @@ -93,7 +97,7 @@ bgp_capability_vty_out (struct vty *vty, struct peer *peer, u_char use_json, jso json_object_int_add(json_cap, "capabilityErrorMultiProtocolAfiUnknown", ntohs (mpc.afi)); break; } - switch (mpc.safi) + switch (safi) { case SAFI_UNICAST: json_object_string_add(json_cap, "capabilityErrorMultiProtocolSafi", "unicast"); @@ -101,7 +105,7 @@ bgp_capability_vty_out (struct vty *vty, struct peer *peer, u_char use_json, jso case SAFI_MULTICAST: json_object_string_add(json_cap, "capabilityErrorMultiProtocolSafi", "multicast"); break; - case SAFI_MPLS_LABELED_VPN: + case SAFI_MPLS_VPN: json_object_string_add(json_cap, "capabilityErrorMultiProtocolSafi", "MPLS-labeled VPN"); break; case SAFI_ENCAP: @@ -115,7 +119,7 @@ bgp_capability_vty_out (struct vty *vty, struct peer *peer, u_char use_json, jso else { vty_out (vty, " Capability error for: Multi protocol "); - switch (ntohs (mpc.afi)) + switch (afi) { case AFI_IP: vty_out (vty, "AFI IPv4, "); @@ -127,7 +131,7 @@ bgp_capability_vty_out (struct vty *vty, struct peer *peer, u_char use_json, jso vty_out (vty, "AFI Unknown %d, ", ntohs (mpc.afi)); break; } - switch (mpc.safi) + switch (safi) { case SAFI_UNICAST: vty_out (vty, "SAFI Unicast"); @@ -135,7 +139,7 @@ bgp_capability_vty_out (struct vty *vty, struct peer *peer, u_char use_json, jso case SAFI_MULTICAST: vty_out (vty, "SAFI Multicast"); break; - case SAFI_MPLS_LABELED_VPN: + case SAFI_MPLS_VPN: vty_out (vty, "SAFI MPLS-labeled VPN"); break; case SAFI_ENCAP: @@ -178,35 +182,6 @@ bgp_capability_mp_data (struct stream *s, struct capability_mp_data *mpc) mpc->safi = stream_getc (s); } -int -bgp_afi_safi_valid_indices (afi_t afi, safi_t *safi) -{ - switch (afi) - { - case AFI_IP: - case AFI_IP6: - switch (*safi) - { - /* BGP MPLS-labeled VPN SAFI isn't contigious with others, remap */ - case SAFI_MPLS_LABELED_VPN: - *safi = SAFI_MPLS_VPN; - case SAFI_UNICAST: - case SAFI_MULTICAST: - case SAFI_MPLS_VPN: - case SAFI_ENCAP: - return 1; - } - break; - case AFI_ETHER: - default: - break; - } - - zlog_debug ("unknown afi/safi (%u/%u)", afi, *safi); - - return 0; -} - /* Set negotiated capability value. */ static int bgp_capability_mp (struct peer *peer, struct capability_header *hdr) @@ -228,7 +203,8 @@ bgp_capability_mp (struct peer *peer, struct capability_header *hdr) zlog_debug ("%s OPEN has MP_EXT CAP for afi/safi: %u/%u", peer->host, mpc.afi, mpc.safi); - if (!bgp_afi_safi_valid_indices (mpc.afi, &mpc.safi)) + /* Convert AFI, SAFI to internal values, check. */ + if (bgp_map_afi_safi_iana2int (mpc.afi, mpc.safi, &mpc.afi, &mpc.safi)) return -1; /* Now safi remapped, and afi/safi are valid array indices */ @@ -271,8 +247,8 @@ bgp_capability_orf_entry (struct peer *peer, struct capability_header *hdr) { struct stream *s = BGP_INPUT (peer); struct capability_orf_entry entry; - afi_t afi; - safi_t safi; + afi_t pkt_afi, afi; + safi_t pkt_safi, safi; u_char type; u_char mode; u_int16_t sm_cap = 0; /* capability send-mode receive */ @@ -282,22 +258,25 @@ bgp_capability_orf_entry (struct peer *peer, struct capability_header *hdr) /* ORF Entry header */ bgp_capability_mp_data (s, &entry.mpc); entry.num = stream_getc (s); - afi = entry.mpc.afi; - safi = entry.mpc.safi; + pkt_afi = entry.mpc.afi; + pkt_safi = entry.mpc.safi; if (bgp_debug_neighbor_events(peer)) zlog_debug ("%s ORF Cap entry for afi/safi: %u/%u", peer->host, entry.mpc.afi, entry.mpc.safi); - /* Check AFI and SAFI. */ - if (!bgp_afi_safi_valid_indices (entry.mpc.afi, &safi)) + /* Convert AFI, SAFI to internal values, check. */ + if (bgp_map_afi_safi_iana2int (pkt_afi, pkt_safi, &afi, &safi)) { zlog_info ("%s Addr-family %d/%d not supported." " Ignoring the ORF capability", - peer->host, entry.mpc.afi, entry.mpc.safi); + peer->host, pkt_afi, pkt_safi); return 0; } + entry.mpc.afi = afi; + entry.mpc.safi = safi; + /* validate number field */ if (CAPABILITY_CODE_ORF_LEN + (entry.num * 2) > hdr->length) { @@ -321,7 +300,7 @@ bgp_capability_orf_entry (struct peer *peer, struct capability_header *hdr) case ORF_MODE_RECEIVE: break; default: - bgp_capability_orf_not_support (peer, afi, safi, type, mode); + bgp_capability_orf_not_support (peer, pkt_afi, pkt_safi, type, mode); continue; } /* ORF Type and afi/safi error checks */ @@ -334,7 +313,7 @@ bgp_capability_orf_entry (struct peer *peer, struct capability_header *hdr) case ORF_TYPE_PREFIX: break; default: - bgp_capability_orf_not_support (peer, afi, safi, type, mode); + bgp_capability_orf_not_support (peer, pkt_afi, pkt_safi, type, mode); continue; } break; @@ -344,12 +323,12 @@ bgp_capability_orf_entry (struct peer *peer, struct capability_header *hdr) case ORF_TYPE_PREFIX_OLD: break; default: - bgp_capability_orf_not_support (peer, afi, safi, type, mode); + bgp_capability_orf_not_support (peer, pkt_afi, pkt_safi, type, mode); continue; } break; default: - bgp_capability_orf_not_support (peer, afi, safi, type, mode); + bgp_capability_orf_not_support (peer, pkt_afi, pkt_safi, type, mode); continue; } @@ -358,7 +337,7 @@ bgp_capability_orf_entry (struct peer *peer, struct capability_header *hdr) || (afi == AFI_IP && safi == SAFI_MULTICAST) || (afi == AFI_IP6 && safi == SAFI_UNICAST))) { - bgp_capability_orf_not_support (peer, afi, safi, type, mode); + bgp_capability_orf_not_support (peer, pkt_afi, pkt_safi, type, mode); continue; } @@ -367,7 +346,7 @@ bgp_capability_orf_entry (struct peer *peer, struct capability_header *hdr) " as %s for afi/safi: %d/%d", peer->host, LOOKUP (orf_type_str, type), LOOKUP (orf_mode_str, mode), - entry.mpc.afi, safi); + pkt_afi, pkt_safi); if (hdr->code == CAPABILITY_CODE_ORF) { @@ -381,7 +360,7 @@ bgp_capability_orf_entry (struct peer *peer, struct capability_header *hdr) } else { - bgp_capability_orf_not_support (peer, afi, safi, type, mode); + bgp_capability_orf_not_support (peer, pkt_afi, pkt_safi, type, mode); continue; } @@ -437,23 +416,26 @@ bgp_capability_restart (struct peer *peer, struct capability_header *caphdr) while (stream_get_getp (s) + 4 <= end) { - afi_t afi = stream_getw (s); - safi_t safi = stream_getc (s); + afi_t afi; + safi_t safi; + afi_t pkt_afi = stream_getw (s); + safi_t pkt_safi = stream_getc (s); u_char flag = stream_getc (s); - if (!bgp_afi_safi_valid_indices (afi, &safi)) + /* Convert AFI, SAFI to internal values, check. */ + if (bgp_map_afi_safi_iana2int (pkt_afi, pkt_safi, &afi, &safi)) { if (bgp_debug_neighbor_events(peer)) zlog_debug ("%s Addr-family %d/%d(afi/safi) not supported." " Ignore the Graceful Restart capability for this AFI/SAFI", - peer->host, afi, safi); + peer->host, pkt_afi, pkt_safi); } else if (!peer->afc[afi][safi]) { if (bgp_debug_neighbor_events(peer)) zlog_debug ("%s Addr-family %d/%d(afi/safi) not enabled." " Ignore the Graceful Restart capability", - peer->host, afi, safi); + peer->host, pkt_afi, pkt_safi); } else { @@ -512,22 +494,25 @@ bgp_capability_addpath (struct peer *peer, struct capability_header *hdr) while (stream_get_getp (s) + 4 <= end) { - afi_t afi = stream_getw (s); - safi_t safi = stream_getc (s); + afi_t afi; + safi_t safi; + afi_t pkt_afi = stream_getw (s); + safi_t pkt_safi = stream_getc (s); u_char send_receive = stream_getc (s); if (bgp_debug_neighbor_events(peer)) zlog_debug ("%s OPEN has AddPath CAP for afi/safi: %u/%u%s%s", - peer->host, afi, safi, + peer->host, pkt_afi, pkt_safi, (send_receive & BGP_ADDPATH_RX) ? ", receive" : "", (send_receive & BGP_ADDPATH_TX) ? ", transmit" : ""); - if (!bgp_afi_safi_valid_indices (afi, &safi)) + /* Convert AFI, SAFI to internal values, check. */ + if (bgp_map_afi_safi_iana2int (pkt_afi, pkt_safi, &afi, &safi)) { if (bgp_debug_neighbor_events(peer)) zlog_debug ("%s Addr-family %d/%d(afi/safi) not supported." " Ignore the Addpath Attribute for this AFI/SAFI", - peer->host, afi, safi); + peer->host, pkt_afi, pkt_safi); continue; } else if (!peer->afc[afi][safi]) @@ -535,7 +520,7 @@ bgp_capability_addpath (struct peer *peer, struct capability_header *hdr) if (bgp_debug_neighbor_events(peer)) zlog_debug ("%s Addr-family %d/%d(afi/safi) not enabled." " Ignore the AddPath capability for this AFI/SAFI", - peer->host, afi, safi); + peer->host, pkt_afi, pkt_safi); continue; } @@ -565,20 +550,21 @@ bgp_capability_enhe (struct peer *peer, struct capability_header *hdr) while (stream_get_getp (s) + 6 <= end) { - afi_t afi = stream_getw (s); - safi_t safi = stream_getw (s); - afi_t nh_afi = stream_getw (s); + afi_t afi, pkt_afi = stream_getw (s); + safi_t safi, pkt_safi = stream_getw (s); + afi_t nh_afi, pkt_nh_afi = stream_getw (s); if (bgp_debug_neighbor_events(peer)) zlog_debug ("%s Received with afi/safi/next-hop afi: %u/%u/%u", - peer->host, afi, safi, nh_afi); + peer->host, pkt_afi, pkt_safi, pkt_nh_afi); - if (!bgp_afi_safi_valid_indices (afi, &safi)) + /* Convert AFI, SAFI to internal values, check. */ + if (bgp_map_afi_safi_iana2int (pkt_afi, pkt_safi, &afi, &safi)) { if (bgp_debug_neighbor_events(peer)) zlog_debug ("%s Addr-family %d/%d(afi/safi) not supported." " Ignore the ENHE Attribute for this AFI/SAFI", - peer->host, afi, safi); + peer->host, pkt_afi, pkt_safi); continue; } @@ -587,11 +573,13 @@ bgp_capability_enhe (struct peer *peer, struct capability_header *hdr) * possibilities, so we ignore other values with a log. Also, only * Unicast SAFI is currently supported (and expected). */ + nh_afi = afi_iana2int (pkt_nh_afi); + if (afi != AFI_IP || safi != SAFI_UNICAST || nh_afi != AFI_IP6) { zlog_warn ("%s Unexpected afi/safi/next-hop afi: %u/%u/%u " "in Extended Next-hop capability, ignoring", - peer->host, afi, safi, nh_afi); + peer->host, pkt_afi, pkt_safi, pkt_nh_afi); continue; } @@ -1174,9 +1162,11 @@ bgp_open_capability_orf (struct stream *s, struct peer *peer, unsigned long orfp; unsigned long numberp; int number_of_orfs = 0; + afi_t pkt_afi; + safi_t pkt_safi; - if (safi == SAFI_MPLS_VPN) - safi = SAFI_MPLS_LABELED_VPN; + /* Convert AFI, SAFI to values for packet. */ + bgp_map_afi_safi_int2iana (afi, safi, &pkt_afi, &pkt_safi); stream_putc (s, BGP_OPEN_OPT_CAP); capp = stream_get_endp (s); /* Set Capability Len Pointer */ @@ -1184,9 +1174,9 @@ bgp_open_capability_orf (struct stream *s, struct peer *peer, stream_putc (s, code); /* Capability Code */ orfp = stream_get_endp (s); /* Set ORF Len Pointer */ stream_putc (s, 0); /* ORF Length */ - stream_putw (s, afi); + stream_putw (s, pkt_afi); stream_putc (s, 0); - stream_putc (s, safi); + stream_putc (s, pkt_safi); numberp = stream_get_endp (s); /* Set Number Pointer */ stream_putc (s, 0); /* Number of ORFs */ @@ -1235,8 +1225,8 @@ bgp_open_capability (struct stream *s, struct peer *peer) { u_char len; unsigned long cp, capp, rcapp; - afi_t afi; - safi_t safi; + afi_t afi, pkt_afi; + safi_t safi, pkt_safi; as_t local_as; u_int32_t restart_time; u_char afi_safi_count = 0; @@ -1254,56 +1244,29 @@ bgp_open_capability (struct stream *s, struct peer *peer) || CHECK_FLAG (peer->flags, PEER_FLAG_DONT_CAPABILITY)) return; - /* IPv4 unicast. */ - if (peer->afc[AFI_IP][SAFI_UNICAST]) - { - peer->afc_adv[AFI_IP][SAFI_UNICAST] = 1; - stream_putc (s, BGP_OPEN_OPT_CAP); - stream_putc (s, CAPABILITY_CODE_MP_LEN + 2); - stream_putc (s, CAPABILITY_CODE_MP); - stream_putc (s, CAPABILITY_CODE_MP_LEN); - stream_putw (s, AFI_IP); - stream_putc (s, 0); - stream_putc (s, SAFI_UNICAST); - } - /* IPv4 multicast. */ - if (peer->afc[AFI_IP][SAFI_MULTICAST]) - { - peer->afc_adv[AFI_IP][SAFI_MULTICAST] = 1; - stream_putc (s, BGP_OPEN_OPT_CAP); - stream_putc (s, CAPABILITY_CODE_MP_LEN + 2); - stream_putc (s, CAPABILITY_CODE_MP); - stream_putc (s, CAPABILITY_CODE_MP_LEN); - stream_putw (s, AFI_IP); - stream_putc (s, 0); - stream_putc (s, SAFI_MULTICAST); - } - /* IPv4 VPN */ - if (peer->afc[AFI_IP][SAFI_MPLS_VPN]) - { - peer->afc_adv[AFI_IP][SAFI_MPLS_VPN] = 1; - stream_putc (s, BGP_OPEN_OPT_CAP); - stream_putc (s, CAPABILITY_CODE_MP_LEN + 2); - stream_putc (s, CAPABILITY_CODE_MP); - stream_putc (s, CAPABILITY_CODE_MP_LEN); - stream_putw (s, AFI_IP); - stream_putc (s, 0); - stream_putc (s, SAFI_MPLS_LABELED_VPN); - } - /* ENCAP */ - if (peer->afc[AFI_IP][SAFI_ENCAP]) - { - peer->afc_adv[AFI_IP][SAFI_ENCAP] = 1; - stream_putc (s, BGP_OPEN_OPT_CAP); - stream_putc (s, CAPABILITY_CODE_MP_LEN + 2); - stream_putc (s, CAPABILITY_CODE_MP); - stream_putc (s, CAPABILITY_CODE_MP_LEN); - stream_putw (s, AFI_IP); - stream_putc (s, 0); - stream_putc (s, SAFI_ENCAP); - } -#ifdef HAVE_IPV6 - /* Currently supporting RFC-5549 for Link-Local peering only */ + /* MP capability for configured AFI, SAFI */ + for (afi = AFI_IP ; afi < AFI_MAX ; afi++) + for (safi = SAFI_UNICAST ; safi < SAFI_MAX ; safi++) + { + if (peer->afc[afi][safi]) + { + /* Convert AFI, SAFI to values for packet. */ + bgp_map_afi_safi_int2iana (afi, safi, &pkt_afi, &pkt_safi); + + peer->afc_adv[afi][safi] = 1; + stream_putc (s, BGP_OPEN_OPT_CAP); + stream_putc (s, CAPABILITY_CODE_MP_LEN + 2); + stream_putc (s, CAPABILITY_CODE_MP); + stream_putc (s, CAPABILITY_CODE_MP_LEN); + stream_putw (s, pkt_afi); + stream_putc (s, 0); + stream_putc (s, pkt_safi); + } + } + + /* Extended nexthop capability - currently supporting RFC-5549 for + * Link-Local peering only + */ if (CHECK_FLAG (peer->flags, PEER_FLAG_CAPABILITY_ENHE) && peer->su.sa.sa_family == AF_INET6 && IN6_IS_ADDR_LINKLOCAL(&peer->su.sin6.sin6_addr)) @@ -1323,55 +1286,6 @@ bgp_open_capability (struct stream *s, struct peer *peer) if (CHECK_FLAG (peer->af_cap[AFI_IP][SAFI_UNICAST], PEER_CAP_ENHE_AF_RCV)) SET_FLAG (peer->af_cap[AFI_IP][SAFI_UNICAST], PEER_CAP_ENHE_AF_NEGO); } - /* IPv6 unicast. */ - if (peer->afc[AFI_IP6][SAFI_UNICAST]) - { - peer->afc_adv[AFI_IP6][SAFI_UNICAST] = 1; - stream_putc (s, BGP_OPEN_OPT_CAP); - stream_putc (s, CAPABILITY_CODE_MP_LEN + 2); - stream_putc (s, CAPABILITY_CODE_MP); - stream_putc (s, CAPABILITY_CODE_MP_LEN); - stream_putw (s, AFI_IP6); - stream_putc (s, 0); - stream_putc (s, SAFI_UNICAST); - } - /* IPv6 multicast. */ - if (peer->afc[AFI_IP6][SAFI_MULTICAST]) - { - peer->afc_adv[AFI_IP6][SAFI_MULTICAST] = 1; - stream_putc (s, BGP_OPEN_OPT_CAP); - stream_putc (s, CAPABILITY_CODE_MP_LEN + 2); - stream_putc (s, CAPABILITY_CODE_MP); - stream_putc (s, CAPABILITY_CODE_MP_LEN); - stream_putw (s, AFI_IP6); - stream_putc (s, 0); - stream_putc (s, SAFI_MULTICAST); - } - /* IPv6 VPN. */ - if (peer->afc[AFI_IP6][SAFI_MPLS_VPN]) - { - peer->afc_adv[AFI_IP6][SAFI_MPLS_VPN] = 1; - stream_putc (s, BGP_OPEN_OPT_CAP); - stream_putc (s, CAPABILITY_CODE_MP_LEN + 2); - stream_putc (s, CAPABILITY_CODE_MP); - stream_putc (s, CAPABILITY_CODE_MP_LEN); - stream_putw (s, AFI_IP6); - stream_putc (s, 0); - stream_putc (s, SAFI_MPLS_LABELED_VPN); - } - /* IPv6 ENCAP. */ - if (peer->afc[AFI_IP6][SAFI_ENCAP]) - { - peer->afc_adv[AFI_IP6][SAFI_ENCAP] = 1; - stream_putc (s, BGP_OPEN_OPT_CAP); - stream_putc (s, CAPABILITY_CODE_MP_LEN + 2); - stream_putc (s, CAPABILITY_CODE_MP); - stream_putc (s, CAPABILITY_CODE_MP_LEN); - stream_putw (s, AFI_IP6); - stream_putc (s, 0); - stream_putc (s, SAFI_ENCAP); - } -#endif /* HAVE_IPV6 */ /* Route refresh. */ SET_FLAG (peer->cap, PEER_CAP_REFRESH_ADV); @@ -1420,8 +1334,11 @@ bgp_open_capability (struct stream *s, struct peer *peer) for (safi = SAFI_UNICAST ; safi < SAFI_MAX ; safi++) if (peer->afc[afi][safi]) { - stream_putw (s, afi); - stream_putc (s, safi); + /* Convert AFI, SAFI to values for packet. */ + bgp_map_afi_safi_int2iana (afi, safi, &pkt_afi, &pkt_safi); + + stream_putw (s, pkt_afi); + stream_putc (s, pkt_safi); if (adv_addpath_tx) { @@ -1535,8 +1452,10 @@ bgp_open_capability (struct stream *s, struct peer *peer) for (safi = SAFI_UNICAST ; safi < SAFI_MAX ; safi++) if (peer->afc[afi][safi]) { - stream_putw (s, afi); - stream_putc (s, (safi == SAFI_MPLS_VPN) ? SAFI_MPLS_LABELED_VPN : safi); + /* Convert AFI, SAFI to values for packet. */ + bgp_map_afi_safi_int2iana (afi, safi, &pkt_afi, &pkt_safi); + stream_putw (s, pkt_afi); + stream_putc (s, pkt_safi); if (bgp_flag_check(peer->bgp, BGP_FLAG_GR_PRESERVE_FWD)) stream_putc (s, RESTART_F_BIT); else diff --git a/bgpd/bgp_open.h b/bgpd/bgp_open.h index 8ec0a5416b..b0a396ec11 100644 --- a/bgpd/bgp_open.h +++ b/bgpd/bgp_open.h @@ -115,6 +115,5 @@ extern int bgp_open_option_parse (struct peer *, u_char, int *); extern void bgp_open_capability (struct stream *, struct peer *); extern void bgp_capability_vty_out (struct vty *, struct peer *, u_char, json_object *); extern as_t peek_for_as4_capability (struct peer *, u_char); -extern int bgp_afi_safi_valid_indices (afi_t, safi_t *); #endif /* _QUAGGA_BGP_OPEN_H */ diff --git a/bgpd/bgp_packet.c b/bgpd/bgp_packet.c index dffca37dd3..38470a3c7e 100644 --- a/bgpd/bgp_packet.c +++ b/bgpd/bgp_packet.c @@ -147,6 +147,8 @@ static struct stream * bgp_update_packet_eor (struct peer *peer, afi_t afi, safi_t safi) { struct stream *s; + afi_t pkt_afi; + safi_t pkt_safi; if (DISABLE_BGP_ANNOUNCE) return NULL; @@ -169,13 +171,16 @@ bgp_update_packet_eor (struct peer *peer, afi_t afi, safi_t safi) } else { + /* Convert AFI, SAFI to values for packet. */ + bgp_map_afi_safi_int2iana (afi, safi, &pkt_afi, &pkt_safi); + /* Total Path Attribute Length */ stream_putw (s, 6); stream_putc (s, BGP_ATTR_FLAG_OPTIONAL); stream_putc (s, BGP_ATTR_MP_UNREACH_NLRI); stream_putc (s, 3); - stream_putw (s, afi); - stream_putc (s, (safi == SAFI_MPLS_VPN) ? SAFI_MPLS_LABELED_VPN : safi); + stream_putw (s, pkt_afi); + stream_putc (s, pkt_safi); } bgp_packet_set_size (s); @@ -690,15 +695,16 @@ bgp_route_refresh_send (struct peer *peer, afi_t afi, safi_t safi, struct stream *s; struct bgp_filter *filter; int orf_refresh = 0; + afi_t pkt_afi; + safi_t pkt_safi; if (DISABLE_BGP_ANNOUNCE) return; filter = &peer->filter[afi][safi]; - /* Adjust safi code. */ - if (safi == SAFI_MPLS_VPN) - safi = SAFI_MPLS_LABELED_VPN; + /* Convert AFI, SAFI to values for packet. */ + bgp_map_afi_safi_int2iana (afi, safi, &pkt_afi, &pkt_safi); s = stream_new (BGP_MAX_PACKET_SIZE); @@ -709,9 +715,9 @@ bgp_route_refresh_send (struct peer *peer, afi_t afi, safi_t safi, bgp_packet_set_marker (s, BGP_MSG_ROUTE_REFRESH_OLD); /* Encode Route Refresh message. */ - stream_putw (s, afi); + stream_putw (s, pkt_afi); stream_putc (s, 0); - stream_putc (s, safi); + stream_putc (s, pkt_safi); if (orf_type == ORF_TYPE_PREFIX || orf_type == ORF_TYPE_PREFIX_OLD) @@ -734,7 +740,7 @@ bgp_route_refresh_send (struct peer *peer, afi_t afi, safi_t safi, zlog_debug ("%s sending REFRESH_REQ to remove ORF(%d) (%s) for afi/safi: %d/%d", peer->host, orf_type, (when_to_refresh == REFRESH_DEFER ? "defer" : "immediate"), - afi, safi); + pkt_afi, pkt_safi); } else { @@ -746,7 +752,7 @@ bgp_route_refresh_send (struct peer *peer, afi_t afi, safi_t safi, zlog_debug ("%s sending REFRESH_REQ with pfxlist ORF(%d) (%s) for afi/safi: %d/%d", peer->host, orf_type, (when_to_refresh == REFRESH_DEFER ? "defer" : "immediate"), - afi, safi); + pkt_afi, pkt_safi); } /* Total ORF Entry Len. */ @@ -761,7 +767,7 @@ bgp_route_refresh_send (struct peer *peer, afi_t afi, safi_t safi, { if (! orf_refresh) zlog_debug ("%s sending REFRESH_REQ for afi/safi: %d/%d", - peer->host, afi, safi); + peer->host, pkt_afi, pkt_safi); } /* Add packet to the peer. */ @@ -776,10 +782,11 @@ bgp_capability_send (struct peer *peer, afi_t afi, safi_t safi, int capability_code, int action) { struct stream *s; + afi_t pkt_afi; + safi_t pkt_safi; - /* Adjust safi code. */ - if (safi == SAFI_MPLS_VPN) - safi = SAFI_MPLS_LABELED_VPN; + /* Convert AFI, SAFI to values for packet. */ + bgp_map_afi_safi_int2iana (afi, safi, &pkt_afi, &pkt_safi); s = stream_new (BGP_MAX_PACKET_SIZE); @@ -792,14 +799,14 @@ bgp_capability_send (struct peer *peer, afi_t afi, safi_t safi, stream_putc (s, action); stream_putc (s, CAPABILITY_CODE_MP); stream_putc (s, CAPABILITY_CODE_MP_LEN); - stream_putw (s, afi); + stream_putw (s, pkt_afi); stream_putc (s, 0); - stream_putc (s, safi); + stream_putc (s, pkt_safi); if (bgp_debug_neighbor_events(peer)) zlog_debug ("%s sending CAPABILITY has %s MP_EXT CAP for afi/safi: %d/%d", peer->host, action == CAPABILITY_ACTION_SET ? - "Advertising" : "Removing", afi, safi); + "Advertising" : "Removing", pkt_afi, pkt_safi); } /* Set packet size. */ @@ -1329,7 +1336,6 @@ bgp_nlri_parse (struct peer *peer, struct attr *attr, struct bgp_nlri *packet) case SAFI_MULTICAST: return bgp_nlri_parse_ip (peer, attr, packet); case SAFI_MPLS_VPN: - case SAFI_MPLS_LABELED_VPN: return bgp_nlri_parse_vpn (peer, attr, packet); case SAFI_ENCAP: return bgp_nlri_parse_encap (peer, attr, packet); @@ -1508,26 +1514,6 @@ bgp_update_receive (struct peer *peer, bgp_size_t size) if (!nlris[i].nlri) continue; - /* We use afi and safi as indices into tables and what not. It would - * be impossible, at this time, to support unknown afi/safis. And - * anyway, the peer needs to be configured to enable the afi/safi - * explicitly which requires UI support. - * - * Ignore unknown afi/safi NLRIs. - * - * Note: This means nlri[x].afi/safi still can not be trusted for - * indexing later in this function! - * - * Note2: This will also remap the wire code-point for VPN safi to the - * internal safi_t point, as needs be. - */ - if(!bgp_afi_safi_valid_indices (nlris[i].afi, &nlris[i].safi)) - { - zlog_info ("%s [Info] UPDATE with unsupported AFI/SAFI %u/%u", - peer->host, nlris[i].afi, nlris[i].safi); - continue; - } - /* NLRI is processed iff the peer if configured for the specific afi/safi */ if (!peer->afc[nlris[i].afi][nlris[i].safi]) { @@ -1586,9 +1572,7 @@ bgp_update_receive (struct peer *peer, bgp_size_t size) safi = SAFI_UNICAST; } else if (attr.flag & ATTR_FLAG_BIT (BGP_ATTR_MP_UNREACH_NLRI) - && nlris[NLRI_MP_WITHDRAW].length == 0 - && bgp_afi_safi_valid_indices (nlris[NLRI_MP_WITHDRAW].afi, - &nlris[NLRI_MP_WITHDRAW].safi)) + && nlris[NLRI_MP_WITHDRAW].length == 0) { afi = nlris[NLRI_MP_WITHDRAW].afi; safi = nlris[NLRI_MP_WITHDRAW].safi; @@ -1727,8 +1711,8 @@ bgp_keepalive_receive (struct peer *peer, bgp_size_t size) static void bgp_route_refresh_receive (struct peer *peer, bgp_size_t size) { - afi_t afi; - safi_t safi; + afi_t pkt_afi, afi; + safi_t pkt_safi, safi; struct stream *s; struct peer_af *paf; struct update_group *updgrp; @@ -1757,28 +1741,22 @@ bgp_route_refresh_receive (struct peer *peer, bgp_size_t size) s = peer->ibuf; /* Parse packet. */ - afi = stream_getw (s); + pkt_afi = stream_getw (s); (void)stream_getc (s); - safi = stream_getc (s); + pkt_safi = stream_getc (s); if (bgp_debug_update(peer, NULL, NULL, 0)) zlog_debug ("%s rcvd REFRESH_REQ for afi/safi: %d/%d", - peer->host, afi, safi); + peer->host, pkt_afi, pkt_safi); - /* Check AFI and SAFI. */ - if ((afi != AFI_IP && afi != AFI_IP6) - || (safi != SAFI_UNICAST && safi != SAFI_MULTICAST - && safi != SAFI_MPLS_LABELED_VPN)) + /* Convert AFI, SAFI to internal values and check. */ + if (bgp_map_afi_safi_iana2int (pkt_afi, pkt_safi, &afi, &safi)) { zlog_info ("%s REFRESH_REQ for unrecognized afi/safi: %d/%d - ignored", - peer->host, afi, safi); + peer->host, pkt_afi, pkt_safi); return; } - /* Adjust safi code. */ - if (safi == SAFI_MPLS_LABELED_VPN) - safi = SAFI_MPLS_VPN; - if (size != BGP_MSG_ROUTE_REFRESH_MIN_SIZE - BGP_HEADER_SIZE) { u_char *end; @@ -1954,8 +1932,8 @@ bgp_capability_msg_parse (struct peer *peer, u_char *pnt, bgp_size_t length) struct capability_mp_data mpc; struct capability_header *hdr; u_char action; - afi_t afi; - safi_t safi; + afi_t pkt_afi, afi; + safi_t pkt_safi, safi; end = pnt + length; @@ -1999,18 +1977,19 @@ bgp_capability_msg_parse (struct peer *peer, u_char *pnt, bgp_size_t length) /* We know MP Capability Code. */ if (hdr->code == CAPABILITY_CODE_MP) { - afi = ntohs (mpc.afi); - safi = mpc.safi; + pkt_afi = ntohs (mpc.afi); + pkt_safi = mpc.safi; /* Ignore capability when override-capability is set. */ if (CHECK_FLAG (peer->flags, PEER_FLAG_OVERRIDE_CAPABILITY)) continue; - if (!bgp_afi_safi_valid_indices (afi, &safi)) + /* Convert AFI, SAFI to internal values. */ + if (bgp_map_afi_safi_iana2int (pkt_afi, pkt_safi, &afi, &safi)) { if (bgp_debug_neighbor_events(peer)) zlog_debug ("%s Dynamic Capability MP_EXT afi/safi invalid " - "(%u/%u)", peer->host, afi, safi); + "(%u/%u)", peer->host, pkt_afi, pkt_safi); continue; } @@ -2020,7 +1999,7 @@ bgp_capability_msg_parse (struct peer *peer, u_char *pnt, bgp_size_t length) peer->host, action == CAPABILITY_ACTION_SET ? "Advertising" : "Removing", - ntohs(mpc.afi) , mpc.safi); + pkt_afi, pkt_safi); if (action == CAPABILITY_ACTION_SET) { diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index 6d8f721bfb..0040c7a144 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -2119,6 +2119,9 @@ int bgp_maximum_prefix_overflow (struct peer *peer, afi_t afi, safi_t safi, int always) { + afi_t pkt_afi; + safi_t pkt_safi; + if (!CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX)) return 0; @@ -2136,15 +2139,15 @@ bgp_maximum_prefix_overflow (struct peer *peer, afi_t afi, if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX_WARNING)) return 0; + /* Convert AFI, SAFI to values for packet. */ + pkt_afi = afi_int2iana (afi); + pkt_safi = safi_int2iana (safi); { u_int8_t ndata[7]; - if (safi == SAFI_MPLS_VPN) - safi = SAFI_MPLS_LABELED_VPN; - - ndata[0] = (afi >> 8); - ndata[1] = afi; - ndata[2] = safi; + ndata[0] = (pkt_afi >> 8); + ndata[1] = pkt_afi; + ndata[2] = pkt_safi; ndata[3] = (peer->pmax[afi][safi] >> 24); ndata[4] = (peer->pmax[afi][safi] >> 16); ndata[5] = (peer->pmax[afi][safi] >> 8); diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c index f9c3f9af4b..5457822f3b 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c @@ -651,6 +651,35 @@ bgp_listen_limit_unset (struct bgp *bgp) return 0; } +int +bgp_map_afi_safi_iana2int (afi_t pkt_afi, safi_t pkt_safi, + afi_t *afi, safi_t *safi) +{ + /* Map from IANA values to internal values, return error if + * values are unrecognized. + */ + *afi = afi_iana2int (pkt_afi); + *safi = safi_iana2int (pkt_safi); + if (*afi == AFI_MAX || *safi == SAFI_MAX) + return -1; + + return 0; +} + +int +bgp_map_afi_safi_int2iana (afi_t afi, safi_t safi, + afi_t *pkt_afi, safi_t *pkt_safi) +{ + /* Map from internal values to IANA values, return error if + * internal values are bad (unexpected). + */ + if (afi == AFI_MAX || safi == SAFI_MAX) + return -1; + *pkt_afi = afi_int2iana (afi); + *pkt_safi = safi_int2iana (safi); + return 0; +} + struct peer_af * peer_af_create (struct peer *peer, afi_t afi, safi_t safi) { diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h index 76e19ac535..9a4d92715e 100644 --- a/bgpd/bgpd.h +++ b/bgpd/bgpd.h @@ -1080,10 +1080,6 @@ struct bgp_nlri #define BGP_DEFAULT_RESTART_TIME 120 #define BGP_DEFAULT_STALEPATH_TIME 360 -/* RFC4364 */ -#define SAFI_MPLS_LABELED_VPN 128 -#define BGP_SAFI_VPN 128 - /* BGP uptime string length. */ #define BGP_UPTIME_LEN 25 @@ -1360,6 +1356,13 @@ extern void bgp_route_map_terminate(void); extern int peer_cmp (struct peer *p1, struct peer *p2); +extern int +bgp_map_afi_safi_iana2int (afi_t pkt_afi, safi_t pkt_safi, + afi_t *afi, safi_t *safi); +extern int +bgp_map_afi_safi_int2iana (afi_t afi, safi_t safi, + afi_t *pkt_afi, safi_t *pkt_safi); + extern struct peer_af * peer_af_create (struct peer *, afi_t, safi_t); extern struct peer_af * peer_af_find (struct peer *, afi_t, safi_t); extern int peer_af_delete (struct peer *, afi_t, safi_t); diff --git a/bgpd/rfapi/rfapi_import.c b/bgpd/rfapi/rfapi_import.c index 25c05e65f8..716a1fb537 100644 --- a/bgpd/rfapi/rfapi_import.c +++ b/bgpd/rfapi/rfapi_import.c @@ -4086,7 +4086,6 @@ rfapiBgpInfoFilteredImportFunction (safi_t safi) switch (safi) { case SAFI_MPLS_VPN: - case BGP_SAFI_VPN: return rfapiBgpInfoFilteredImportVPN; case SAFI_ENCAP: @@ -4203,7 +4202,7 @@ rfapiProcessUpdate ( label); } - if (safi == SAFI_MPLS_VPN || safi == BGP_SAFI_VPN) + if (safi == SAFI_MPLS_VPN) { vnc_direct_bgp_rh_add_route (bgp, afi, p, peer, attr); } @@ -4332,7 +4331,7 @@ rfapiProcessWithdraw ( } /* TBD the deletion should happen after the lifetime expires */ - if (safi == SAFI_MPLS_VPN || safi == BGP_SAFI_VPN) + if (safi == SAFI_MPLS_VPN) vnc_direct_bgp_rh_del_route (bgp, afi, p, peer); if (safi == SAFI_MPLS_VPN) diff --git a/lib/zebra.h b/lib/zebra.h index 3a9ad15bf4..5a58cf8e6e 100644 --- a/lib/zebra.h +++ b/lib/zebra.h @@ -473,9 +473,28 @@ typedef enum { #define SAFI_MULTICAST 2 #define SAFI_MPLS_VPN 3 #define SAFI_RESERVED_4 4 -#define SAFI_ENCAP 7 /* per IANA */ +#define SAFI_ENCAP 5 #define SAFI_RESERVED_5 5 -#define SAFI_MAX 8 +#define SAFI_MAX 6 + +/* + * The above AFI and SAFI definitions are for internal use. The protocol + * definitions (IANA values) as for example used in BGP protocol packets + * are defined below and these will get mapped to/from the internal values + * in the appropriate places. + * The rationale is that the protocol (IANA) values may be sparse and are + * not optimal for use in data-structure sizing. + * Note: Only useful (i.e., supported) values are defined below. + */ +#define IANA_AFI_RESERVED 0 +#define IANA_AFI_IPV4 1 +#define IANA_AFI_IPV6 2 + +#define IANA_SAFI_RESERVED 0 +#define IANA_SAFI_UNICAST 1 +#define IANA_SAFI_MULTICAST 2 +#define IANA_SAFI_ENCAP 7 +#define IANA_SAFI_MPLS_VPN 128 /* Default Administrative Distance of each protocol. */ #define ZEBRA_KERNEL_DISTANCE_DEFAULT 0 @@ -509,4 +528,48 @@ typedef uint32_t route_tag_t; #define ROUTE_TAG_MAX UINT32_MAX #define ROUTE_TAG_PRI PRIu32 +static inline afi_t afi_iana2int (afi_t afi) +{ + if (afi == IANA_AFI_IPV4) + return AFI_IP; + if (afi == IANA_AFI_IPV6) + return AFI_IP6; + return AFI_MAX; +} + +static inline afi_t afi_int2iana (afi_t afi) +{ + if (afi == AFI_IP) + return IANA_AFI_IPV4; + if (afi == AFI_IP6) + return IANA_AFI_IPV6; + return IANA_AFI_RESERVED; +} + +static inline safi_t safi_iana2int (safi_t safi) +{ + if (safi == IANA_SAFI_UNICAST) + return SAFI_UNICAST; + if (safi == IANA_SAFI_MULTICAST) + return SAFI_MULTICAST; + if (safi == IANA_SAFI_MPLS_VPN) + return SAFI_MPLS_VPN; + if (safi == IANA_SAFI_ENCAP) + return SAFI_ENCAP; + return SAFI_MAX; +} + +static inline safi_t safi_int2iana (safi_t safi) +{ + if (safi == SAFI_UNICAST) + return IANA_SAFI_UNICAST; + if (safi == SAFI_MULTICAST) + return IANA_SAFI_MULTICAST; + if (safi == SAFI_MPLS_VPN) + return IANA_SAFI_MPLS_VPN; + if (safi == SAFI_ENCAP) + return IANA_SAFI_ENCAP; + return IANA_SAFI_RESERVED; +} + #endif /* _ZEBRA_H */ diff --git a/tests/bgp_capability_test.c b/tests/bgp_capability_test.c index 7fa4be5611..3ee6a121e4 100644 --- a/tests/bgp_capability_test.c +++ b/tests/bgp_capability_test.c @@ -124,21 +124,21 @@ static struct test_segment mp_segments[] = "MP IP6/MPLS-labeled VPN", { CAPABILITY_CODE_MP, 0x4, 0x0, 0x2, 0x0, 0x80 }, 6, SHOULD_PARSE, 0, - 1, AFI_IP6, SAFI_MPLS_LABELED_VPN, VALID_AFI, + 1, AFI_IP6, IANA_SAFI_MPLS_VPN, VALID_AFI, }, /* 7 */ { "MP5", "MP IP6/MPLS-VPN", { CAPABILITY_CODE_MP, 0x4, 0x0, 0x2, 0x0, 0x4 }, 6, SHOULD_PARSE, 0, - 1, AFI_IP6, SAFI_MPLS_VPN, VALID_AFI, + 1, AFI_IP6, IANA_SAFI_MPLS_VPN, VALID_AFI, }, /* 8 */ { "MP6", "MP IP4/MPLS-laveled VPN", { CAPABILITY_CODE_MP, 0x4, 0x0, 0x1, 0x0, 0x80 }, 6, SHOULD_PARSE, 0, - 1, AFI_IP, SAFI_MPLS_LABELED_VPN, VALID_AFI, + 1, AFI_IP, IANA_SAFI_MPLS_VPN, VALID_AFI, }, /* 10 */ { "MP8", @@ -585,22 +585,26 @@ parse_test (struct peer *peer, struct test_segment *t, int type) if (!ret && t->validate_afi) { - safi_t safi = t->safi; + afi_t afi; + safi_t safi; - if (bgp_afi_safi_valid_indices (t->afi, &safi) != t->afi_valid) - failed++; - - printf ("MP: %u/%u (%u): recv %u, nego %u\n", - t->afi, t->safi, safi, - peer->afc_recv[t->afi][safi], - peer->afc_nego[t->afi][safi]); + /* Convert AFI, SAFI to internal values, check. */ + if (bgp_map_afi_safi_iana2int (t->afi, t->safi, &afi, &safi)) + { + if (t->afi_valid == VALID_AFI) + failed++; + } + printf ("MP: %u(%u)/%u(%u): recv %u, nego %u\n", + t->afi, afi, t->safi, safi, + peer->afc_recv[afi][safi], + peer->afc_nego[afi][safi]); if (t->afi_valid == VALID_AFI) { - if (!peer->afc_recv[t->afi][safi]) + if (!peer->afc_recv[afi][safi]) failed++; - if (!peer->afc_nego[t->afi][safi]) + if (!peer->afc_nego[afi][safi]) failed++; } } diff --git a/tests/bgp_mp_attr_test.c b/tests/bgp_mp_attr_test.c index dfb8ed9f7a..f7c2af4405 100644 --- a/tests/bgp_mp_attr_test.c +++ b/tests/bgp_mp_attr_test.c @@ -317,7 +317,7 @@ static struct test_segment { { "IPv4-VPNv4", "IPv4/VPNv4 MP Reach, RD, Nexthop, 2 NLRIs", { - /* AFI / SAFI */ 0x0, AFI_IP, SAFI_MPLS_LABELED_VPN, + /* AFI / SAFI */ 0x0, AFI_IP, IANA_SAFI_MPLS_VPN, /* nexthop bytes */ 12, /* RD */ 0, 0, 0, 0, /* RD defined to be 0 */ 0, 0, 0, 0, @@ -338,12 +338,12 @@ static struct test_segment { }, (4 + 12 + 1 + (1+3+8+2) + (1+3+8+3)), SHOULD_PARSE, - AFI_IP, SAFI_MPLS_LABELED_VPN, VALID_AFI, + AFI_IP, IANA_SAFI_MPLS_VPN, VALID_AFI, }, { "IPv4-VPNv4-bogus-plen", "IPv4/MPLS-labeled VPN MP Reach, RD, Nexthop, NLRI / bogus p'len", { - /* AFI / SAFI */ 0x0, AFI_IP, SAFI_MPLS_LABELED_VPN, + /* AFI / SAFI */ 0x0, AFI_IP, IANA_SAFI_MPLS_VPN, /* nexthop bytes */ 12, /* RD */ 0, 0, 1, 2, 0, 0xff, 3, 4, @@ -355,12 +355,12 @@ static struct test_segment { }, (3 + 1 + 3*4 + 1 + 3 + 4 + 1), SHOULD_ERR, - AFI_IP, SAFI_MPLS_LABELED_VPN, VALID_AFI, + AFI_IP, IANA_SAFI_MPLS_VPN, VALID_AFI, }, { "IPv4-VPNv4-plen1-short", "IPv4/VPNv4 MP Reach, RD, Nexthop, 2 NLRIs, 1st plen short", { - /* AFI / SAFI */ 0x0, AFI_IP, SAFI_MPLS_LABELED_VPN, + /* AFI / SAFI */ 0x0, AFI_IP, IANA_SAFI_MPLS_VPN, /* nexthop bytes */ 12, /* RD */ 0, 0, 0, 0, /* RD defined to be 0 */ 0, 0, 0, 0, @@ -381,12 +381,12 @@ static struct test_segment { }, (4 + 12 + 1 + (1+3+8+2) + (1+3+8+3)), SHOULD_ERR, - AFI_IP, SAFI_MPLS_LABELED_VPN, VALID_AFI, + AFI_IP, IANA_SAFI_MPLS_VPN, VALID_AFI, }, { "IPv4-VPNv4-plen1-long", "IPv4/VPNv4 MP Reach, RD, Nexthop, 2 NLRIs, 1st plen long", { - /* AFI / SAFI */ 0x0, AFI_IP, SAFI_MPLS_LABELED_VPN, + /* AFI / SAFI */ 0x0, AFI_IP, IANA_SAFI_MPLS_VPN, /* nexthop bytes */ 12, /* RD */ 0, 0, 0, 0, /* RD defined to be 0 */ 0, 0, 0, 0, @@ -407,12 +407,12 @@ static struct test_segment { }, (4 + 12 + 1 + (1+3+8+2) + (1+3+8+3)), SHOULD_ERR, - AFI_IP, SAFI_MPLS_LABELED_VPN, VALID_AFI, + AFI_IP, IANA_SAFI_MPLS_VPN, VALID_AFI, }, { "IPv4-VPNv4-plenn-long", "IPv4/VPNv4 MP Reach, RD, Nexthop, 3 NLRIs, last plen long", { - /* AFI / SAFI */ 0x0, AFI_IP, SAFI_MPLS_LABELED_VPN, + /* AFI / SAFI */ 0x0, AFI_IP, IANA_SAFI_MPLS_VPN, /* nexthop bytes */ 12, /* RD */ 0, 0, 0, 0, /* RD defined to be 0 */ 0, 0, 0, 0, @@ -434,12 +434,12 @@ static struct test_segment { }, (4 + 12 + 1 + (1+3+8+2) + (1+3+8+3) + 1), SHOULD_ERR, - AFI_IP, SAFI_MPLS_LABELED_VPN, VALID_AFI, + AFI_IP, IANA_SAFI_MPLS_VPN, VALID_AFI, }, { "IPv4-VPNv4-plenn-short", "IPv4/VPNv4 MP Reach, RD, Nexthop, 2 NLRIs, last plen short", { - /* AFI / SAFI */ 0x0, AFI_IP, SAFI_MPLS_LABELED_VPN, + /* AFI / SAFI */ 0x0, AFI_IP, IANA_SAFI_MPLS_VPN, /* nexthop bytes */ 12, /* RD */ 0, 0, 0, 0, /* RD defined to be 0 */ 0, 0, 0, 0, @@ -460,12 +460,12 @@ static struct test_segment { }, (4 + 12 + 1 + (1+3+8+2) + (1+3+8+3)), SHOULD_ERR, - AFI_IP, SAFI_MPLS_LABELED_VPN, VALID_AFI, + AFI_IP, IANA_SAFI_MPLS_VPN, VALID_AFI, }, { "IPv4-VPNv4-bogus-rd-type", "IPv4/VPNv4 MP Reach, RD, NH, 2 NLRI, unknown RD in 1st (log, but parse)", { - /* AFI / SAFI */ 0x0, AFI_IP, SAFI_MPLS_LABELED_VPN, + /* AFI / SAFI */ 0x0, AFI_IP, IANA_SAFI_MPLS_VPN, /* nexthop bytes */ 12, /* RD */ 0, 0, 0, 0, /* RD defined to be 0 */ 0, 0, 0, 0, @@ -486,12 +486,12 @@ static struct test_segment { }, (4 + 12 + 1 + (1+3+8+2) + (1+3+8+3)), SHOULD_PARSE, - AFI_IP, SAFI_MPLS_LABELED_VPN, VALID_AFI, + AFI_IP, IANA_SAFI_MPLS_VPN, VALID_AFI, }, { "IPv4-VPNv4-0-nlri", "IPv4/VPNv4 MP Reach, RD, Nexthop, 3 NLRI, 3rd 0 bogus", { - /* AFI / SAFI */ 0x0, AFI_IP, SAFI_MPLS_LABELED_VPN, + /* AFI / SAFI */ 0x0, AFI_IP, IANA_SAFI_MPLS_VPN, /* nexthop bytes */ 12, /* RD */ 0, 0, 0, 0, /* RD defined to be 0 */ 0, 0, 0, 0, @@ -513,7 +513,7 @@ static struct test_segment { }, (4 + 12 + 1 + (1+3+8+2) + (1+3+8+3) + 1), SHOULD_ERR, - AFI_IP, SAFI_MPLS_LABELED_VPN, VALID_AFI, + AFI_IP, IANA_SAFI_MPLS_VPN, VALID_AFI, }, /* From bug #385 */ @@ -625,7 +625,7 @@ static struct test_segment mp_unreach_segments [] = { "IPv4-unreach-VPNv4", "IPv4/MPLS-labeled VPN MP Unreach, RD, 3 NLRIs", { - /* AFI / SAFI */ 0x0, AFI_IP, SAFI_MPLS_LABELED_VPN, + /* AFI / SAFI */ 0x0, AFI_IP, IANA_SAFI_MPLS_VPN, /* NLRI tuples */ 88 + 16, 0, 1, 2, /* tag */ /* rd, 8 octets */ @@ -641,7 +641,7 @@ static struct test_segment mp_unreach_segments [] = }, (3 + (1+3+8+2) + (1+3+8+3)), SHOULD_PARSE, - AFI_IP, SAFI_MPLS_LABELED_VPN, VALID_AFI, + AFI_IP, IANA_SAFI_MPLS_VPN, VALID_AFI, }, { NULL, NULL, {0}, 0, 0} }; @@ -656,19 +656,6 @@ handle_result (struct peer *peer, struct test_segment *t, { int oldfailed = failed; - if (!parse_ret) - { - safi_t safi = t->safi; - - if (bgp_afi_safi_valid_indices (t->afi, &safi) != t->afi_valid) - failed++; - - printf ("MP: %u/%u (%u): recv %u, nego %u\n", - t->afi, t->safi, safi, - peer->afc_recv[t->afi][safi], - peer->afc_nego[t->afi][safi]); - } - printf ("mp attr parsed?: %s\n", parse_ret ? "no" : "yes"); if (!parse_ret) printf ("nrli parsed?: %s\n", nlri_ret ? "no" : "yes"); @@ -720,9 +707,20 @@ parse_test (struct peer *peer, struct test_segment *t, int type) parse_ret = bgp_mp_reach_parse (&attr_args, &nlri); else parse_ret = bgp_mp_unreach_parse (&attr_args, &nlri); - - if (parse_ret == 0 && t->afi_valid == VALID_AFI) - assert (nlri.afi == t->afi && nlri.safi == t->safi); + if (!parse_ret) + { + afi_t pkt_afi; + safi_t pkt_safi; + + /* Convert AFI, SAFI to internal values, check. */ + if (bgp_map_afi_safi_int2iana (nlri.afi, nlri.safi, &pkt_afi, &pkt_safi)) + assert (0); + + printf ("MP: %u(%u)/%u(%u): recv %u, nego %u\n", + nlri.afi , pkt_afi, nlri.safi, pkt_safi, + peer->afc_recv[nlri.afi][nlri.safi], + peer->afc_nego[nlri.afi][nlri.safi]); + } if (!parse_ret) { @@ -731,7 +729,7 @@ parse_test (struct peer *peer, struct test_segment *t, int type) else nlri_ret = bgp_nlri_parse (peer, NULL, &nlri); } - + zlog_err("xxxxxxxxxxxxxxxx nlri ret %u", nlri_ret); handle_result (peer, t, parse_ret, nlri_ret); } -- 2.39.5