From 80e71dcd1fffe1126954d30c13897d90512329fa Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Wed, 4 Jan 2017 08:03:14 -0500 Subject: lib: Update ZAPI to version 4 and HEADER_MARKER to 254 Update the ZEBRA_HEADER_MARKER to 254. This will differentiate ourselves from Quagga. Zebra should not listen to people not properly using the right programs now. Update the ZAPI version number to 4. Signed-off-by: Donald Sharp --- lib/zebra.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/zebra.h') diff --git a/lib/zebra.h b/lib/zebra.h index a67713c30d..420f237176 100644 --- a/lib/zebra.h +++ b/lib/zebra.h @@ -411,7 +411,7 @@ typedef enum { * the command value in the old zserv header. To allow old and new * Zserv headers to be distinguished from each other. */ -#define ZEBRA_HEADER_MARKER 255 +#define ZEBRA_HEADER_MARKER 254 /* Zebra route's types are defined in route_types.h */ #include "route_types.h" -- cgit v1.2.3 From 268fef65f965242757975908379c93002200fbaa Mon Sep 17 00:00:00 2001 From: Philippe Guibert Date: Wed, 21 Dec 2016 08:16:06 +0100 Subject: lib: add SAFI_RESERVED_4 value This value is used to limit certain feature to the safi values until that reserved value. Signed-off-by: Philippe Guibert --- lib/zebra.h | 1 + 1 file changed, 1 insertion(+) (limited to 'lib/zebra.h') diff --git a/lib/zebra.h b/lib/zebra.h index 5bb3590abd..345d3e2d8a 100644 --- a/lib/zebra.h +++ b/lib/zebra.h @@ -473,6 +473,7 @@ typedef enum { #define SAFI_MULTICAST 2 #define SAFI_RESERVED_3 3 #define SAFI_MPLS_VPN 4 +#define SAFI_RESERVED_4 4 #define SAFI_ENCAP 7 /* per IANA */ #define SAFI_MAX 8 -- cgit v1.2.3 From db19215a73cd429f04543f75f80ffb989b54d8c3 Mon Sep 17 00:00:00 2001 From: Philippe Guibert Date: Wed, 21 Dec 2016 08:21:02 +0100 Subject: lib: remove SAFI_RESERVED_3 and move SAFI_MPLS to that value Because SAFI_RESERVED_3 value is no more used, the SAFI_MPLS value is lowered to that value. Signed-off-by: Philippe Guibert --- lib/zebra.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'lib/zebra.h') diff --git a/lib/zebra.h b/lib/zebra.h index 345d3e2d8a..f9cf21984f 100644 --- a/lib/zebra.h +++ b/lib/zebra.h @@ -471,8 +471,7 @@ typedef enum { /* Subsequent Address Family Identifier. */ #define SAFI_UNICAST 1 #define SAFI_MULTICAST 2 -#define SAFI_RESERVED_3 3 -#define SAFI_MPLS_VPN 4 +#define SAFI_MPLS_VPN 3 #define SAFI_RESERVED_4 4 #define SAFI_ENCAP 7 /* per IANA */ #define SAFI_MAX 8 -- cgit v1.2.3 From 4d5b4f7bd9d12f4755caf31ce8df3570d55d8575 Mon Sep 17 00:00:00 2001 From: Julien Courtat Date: Wed, 25 May 2016 17:28:31 +0200 Subject: bgpd: graceful restart for vpnv4 address family This patch enable the support of graceful restart for routes sets with vpnv4 address family format. In this specific case, data model is slightly different and some additional processing must be done when accessing bgp tables and nodes. The clearing stale algorithm takes into account the specificity where the 2 node level for MPLS has to be reached. Signed-off-by: Julien Courtat Signed-off-by: Philippe Guibert --- bgpd/bgp_fsm.c | 8 ++++---- bgpd/bgp_route.c | 38 +++++++++++++++++++++++++++++--------- bgpd/bgpd.c | 2 +- lib/zebra.h | 1 + 4 files changed, 35 insertions(+), 14 deletions(-) (limited to 'lib/zebra.h') diff --git a/bgpd/bgp_fsm.c b/bgpd/bgp_fsm.c index 60a6475330..a71364381e 100644 --- a/bgpd/bgp_fsm.c +++ b/bgpd/bgp_fsm.c @@ -509,7 +509,7 @@ bgp_graceful_restart_timer_expire (struct thread *thread) /* NSF delete stale route */ for (afi = AFI_IP ; afi < AFI_MAX ; afi++) - for (safi = SAFI_UNICAST ; safi < SAFI_RESERVED_3 ; safi++) + for (safi = SAFI_UNICAST ; safi < SAFI_RESERVED_4 ; safi++) if (peer->nsf[afi][safi]) bgp_clear_stale_route (peer, afi, safi); @@ -542,7 +542,7 @@ bgp_graceful_stale_timer_expire (struct thread *thread) /* NSF delete stale route */ for (afi = AFI_IP ; afi < AFI_MAX ; afi++) - for (safi = SAFI_UNICAST ; safi < SAFI_RESERVED_3 ; safi++) + for (safi = SAFI_UNICAST ; safi < SAFI_RESERVED_4 ; safi++) if (peer->nsf[afi][safi]) bgp_clear_stale_route (peer, afi, safi); @@ -1051,7 +1051,7 @@ bgp_stop (struct peer *peer) UNSET_FLAG (peer->sflags, PEER_STATUS_NSF_MODE); for (afi = AFI_IP ; afi < AFI_MAX ; afi++) - for (safi = SAFI_UNICAST ; safi < SAFI_RESERVED_3 ; safi++) + for (safi = SAFI_UNICAST ; safi < SAFI_RESERVED_4 ; safi++) peer->nsf[afi][safi] = 0; } @@ -1468,7 +1468,7 @@ bgp_establish (struct peer *peer) /* graceful restart */ UNSET_FLAG (peer->sflags, PEER_STATUS_NSF_WAIT); for (afi = AFI_IP ; afi < AFI_MAX ; afi++) - for (safi = SAFI_UNICAST ; safi < SAFI_RESERVED_3 ; safi++) + for (safi = SAFI_UNICAST ; safi < SAFI_RESERVED_4 ; safi++) { if (peer->afc_nego[afi][safi] && CHECK_FLAG (peer->cap, PEER_CAP_RESTART_ADV) diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index cfc4ec3407..1e9aa4bb2a 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -3307,17 +3307,37 @@ bgp_clear_stale_route (struct peer *peer, afi_t afi, safi_t safi) struct bgp_info *ri; struct bgp_table *table; - table = peer->bgp->rib[afi][safi]; + if ( safi == SAFI_MPLS_VPN) + { + for (rn = bgp_table_top (peer->bgp->rib[afi][safi]); rn; rn = bgp_route_next (rn)) + { + struct bgp_node *rm; + struct bgp_info *ri; - for (rn = bgp_table_top (table); rn; rn = bgp_route_next (rn)) + /* look for neighbor in tables */ + if ((table = rn->info) != NULL) + { + for (rm = bgp_table_top (table); rm; rm = bgp_route_next (rm)) + for (ri = rm->info; ri; ri = ri->next) + if (ri->peer == peer) + { + if (CHECK_FLAG (ri->flags, BGP_INFO_STALE)) + bgp_rib_remove (rm, ri, peer, afi, safi); + break; + } + } + } + } + else { - for (ri = rn->info; ri; ri = ri->next) - if (ri->peer == peer) - { - if (CHECK_FLAG (ri->flags, BGP_INFO_STALE)) - bgp_rib_remove (rn, ri, peer, afi, safi); - break; - } + for (rn = bgp_table_top (peer->bgp->rib[afi][safi]); rn; rn = bgp_route_next (rn)) + for (ri = rn->info; ri; ri = ri->next) + if (ri->peer == peer) + { + if (CHECK_FLAG (ri->flags, BGP_INFO_STALE)) + bgp_rib_remove (rn, ri, peer, afi, safi); + break; + } } } diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c index 30f6e0d859..68ad6bbe11 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c @@ -1902,7 +1902,7 @@ peer_nsf_stop (struct peer *peer) UNSET_FLAG (peer->sflags, PEER_STATUS_NSF_MODE); for (afi = AFI_IP ; afi < AFI_MAX ; afi++) - for (safi = SAFI_UNICAST ; safi < SAFI_RESERVED_3 ; safi++) + for (safi = SAFI_UNICAST ; safi < SAFI_RESERVED_4 ; safi++) peer->nsf[afi][safi] = 0; if (peer->t_gr_restart) diff --git a/lib/zebra.h b/lib/zebra.h index f9cf21984f..fd1aa3cf7d 100644 --- a/lib/zebra.h +++ b/lib/zebra.h @@ -474,6 +474,7 @@ typedef enum { #define SAFI_MPLS_VPN 3 #define SAFI_RESERVED_4 4 #define SAFI_ENCAP 7 /* per IANA */ +#define SAFI_RESERVED_5 5 #define SAFI_MAX 8 /* Default Administrative Distance of each protocol. */ -- cgit v1.2.3 From 9cabb64b320a946b401daa3f6ee7adcefe1548b6 Mon Sep 17 00:00:00 2001 From: vivek Date: Wed, 15 Jun 2016 10:25:35 -0700 Subject: 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(-) (limited to 'lib/zebra.h') 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); } -- cgit v1.2.3