/* BGP open message handling
- Copyright (C) 1998, 1999 Kunihiro Ishiguro
-
-This file is part of GNU Zebra.
-
-GNU Zebra is free software; you can redistribute it and/or modify it
-under the terms of the GNU General Public License as published by the
-Free Software Foundation; either version 2, or (at your option) any
-later version.
-
-GNU Zebra is distributed in the hope that it will be useful, but
-WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with GNU Zebra; see the file COPYING. If not, write to the Free
-Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
-02111-1307, USA. */
+ * Copyright (C) 1998, 1999 Kunihiro Ishiguro
+ *
+ * This file is part of GNU Zebra.
+ *
+ * GNU Zebra is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * GNU Zebra is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; see the file COPYING; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
#include <zebra.h>
vty_out (vty, "SAFI Unknown %d ", mpc.safi);
break;
}
- vty_out (vty, "%s", VTY_NEWLINE);
+ vty_out (vty, "\n");
}
}
else if (hdr->code >= 128)
{
{ ORF_TYPE_PREFIX, "Prefixlist" },
{ ORF_TYPE_PREFIX_OLD, "Prefixlist (old)" },
+ { 0 }
};
-static const int orf_type_str_max = array_size(orf_type_str);
static const struct message orf_mode_str[] =
{
{ ORF_MODE_RECEIVE, "Receive" },
{ ORF_MODE_SEND, "Send" },
{ ORF_MODE_BOTH, "Both" },
+ { 0 }
};
-static const int orf_mode_str_max = array_size(orf_mode_str);
static int
bgp_capability_orf_entry (struct peer *peer, struct capability_header *hdr)
{
struct stream *s = BGP_INPUT (peer);
- struct capability_orf_entry entry;
+ struct capability_mp_data mpc;
+ u_char num;
iana_afi_t pkt_afi;
afi_t afi;
safi_t pkt_safi, safi;
int i;
/* ORF Entry header */
- bgp_capability_mp_data (s, &entry.mpc);
- entry.num = stream_getc (s);
- pkt_afi = entry.mpc.afi;
- pkt_safi = entry.mpc.safi;
+ bgp_capability_mp_data (s, &mpc);
+ num = stream_getc (s);
+ pkt_afi = mpc.afi;
+ pkt_safi = 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);
+ peer->host, mpc.afi, mpc.safi);
/* Convert AFI, SAFI to internal values, check. */
if (bgp_map_afi_safi_iana2int (pkt_afi, pkt_safi, &afi, &safi))
return 0;
}
- entry.mpc.afi = pkt_afi;
- entry.mpc.safi = safi;
+ mpc.afi = pkt_afi;
+ mpc.safi = safi;
/* validate number field */
- if (CAPABILITY_CODE_ORF_LEN + (entry.num * 2) > hdr->length)
+ if (CAPABILITY_CODE_ORF_LEN + (num * 2) > hdr->length)
{
zlog_info ("%s ORF Capability entry length error,"
" Cap length %u, num %u",
- peer->host, hdr->length, entry.num);
+ peer->host, hdr->length, num);
bgp_notify_send (peer, BGP_NOTIFY_OPEN_ERR, BGP_NOTIFY_OPEN_MALFORMED_ATTR);
return -1;
}
- for (i = 0 ; i < entry.num ; i++)
+ for (i = 0 ; i < num ; i++)
{
type = stream_getc(s);
mode = stream_getc(s);
if (bgp_debug_neighbor_events(peer))
zlog_debug ("%s OPEN has %s ORF capability"
" as %s for afi/safi: %d/%d",
- peer->host, LOOKUP (orf_type_str, type),
- LOOKUP (orf_mode_str, mode),
+ peer->host, lookup_msg(orf_type_str, type, NULL),
+ lookup_msg(orf_mode_str, mode, NULL),
pkt_afi, pkt_safi);
if (hdr->code == CAPABILITY_CODE_ORF)
/* RFC 5549 specifies use of this capability only for IPv4 AFI, with
* the Nexthop AFI being IPv6. A future spec may introduce other
* possibilities, so we ignore other values with a log. Also, only
- * Unicast SAFI is currently supported (and expected).
+ * SAFI_UNICAST and SAFI_LABELED_UNICAST are currently supported (and expected).
*/
nh_afi = afi_iana2int (pkt_nh_afi);
- if (afi != AFI_IP || safi != SAFI_UNICAST || nh_afi != AFI_IP6)
+ if (afi != AFI_IP || nh_afi != AFI_IP6 || !(safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST))
{
zlog_warn ("%s Unexpected afi/safi/next-hop afi: %u/%u/%u "
"in Extended Next-hop capability, ignoring",
{ CAPABILITY_CODE_DYNAMIC_OLD, "Dynamic (Old)" },
{ CAPABILITY_CODE_REFRESH_OLD, "Route Refresh (Old)" },
{ CAPABILITY_CODE_ORF_OLD, "ORF (Old)" },
- { CAPABILITY_CODE_FQDN, "FQDN" },
+ { CAPABILITY_CODE_FQDN, "FQDN" },
+ { 0 }
};
-static const int capcode_str_max = array_size(capcode_str);
/* Minimum sizes for length field of each cap (so not inc. the header) */
static const size_t cap_minsizes[] =
if (bgp_debug_neighbor_events(peer))
zlog_debug ("%s OPEN has %s capability (%u), length %u",
peer->host,
- LOOKUP (capcode_str, caphdr.code),
+ lookup_msg(capcode_str, caphdr.code, NULL),
caphdr.code, caphdr.length);
/* Length sanity check, type-specific, for known capabilities */
zlog_info ("%s %s Capability length error: got %u,"
" expected at least %u",
peer->host,
- LOOKUP (capcode_str, caphdr.code),
+ lookup_msg(capcode_str, caphdr.code, NULL),
caphdr.length,
(unsigned) cap_minsizes[caphdr.code]);
bgp_notify_send (peer, BGP_NOTIFY_OPEN_ERR, BGP_NOTIFY_OPEN_MALFORMED_ATTR);
zlog_info ("%s %s Capability length error: got %u,"
" expected a multiple of %u",
peer->host,
- LOOKUP (capcode_str, caphdr.code),
+ lookup_msg(capcode_str, caphdr.code, NULL),
caphdr.length,
(unsigned) cap_modsizes[caphdr.code]);
bgp_notify_send (peer, BGP_NOTIFY_OPEN_ERR,
{
if (stream_get_getp(s) > (start + caphdr.length))
zlog_warn ("%s Cap-parser for %s read past cap-length, %u!",
- peer->host, LOOKUP (capcode_str, caphdr.code),
+ peer->host, lookup_msg(capcode_str, caphdr.code, NULL),
caphdr.length);
stream_set_getp (s, start + caphdr.length);
}
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) &&
+ afi == AFI_IP &&
+ (safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST))
+ {
+ /* RFC 5549 Extended Next Hop Encoding */
+ SET_FLAG (peer->cap, PEER_CAP_ENHE_ADV);
+ stream_putc (s, BGP_OPEN_OPT_CAP);
+ stream_putc (s, CAPABILITY_CODE_ENHE_LEN + 2);
+ stream_putc (s, CAPABILITY_CODE_ENHE);
+ stream_putc (s, CAPABILITY_CODE_ENHE_LEN);
+
+ SET_FLAG (peer->af_cap[AFI_IP][safi], PEER_CAP_ENHE_AF_ADV);
+ stream_putw (s, pkt_afi);
+ stream_putw (s, pkt_safi);
+ stream_putw (s, afi_int2iana(AFI_IP6));
+
+ if (CHECK_FLAG (peer->af_cap[afi][safi], PEER_CAP_ENHE_AF_RCV))
+ SET_FLAG (peer->af_cap[afi][safi], PEER_CAP_ENHE_AF_NEGO);
+ }
}
}
- /* 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))
- {
- /* RFC 5549 Extended Next Hop Encoding */
- SET_FLAG (peer->cap, PEER_CAP_ENHE_ADV);
- stream_putc (s, BGP_OPEN_OPT_CAP);
- stream_putc (s, CAPABILITY_CODE_ENHE_LEN + 2);
- stream_putc (s, CAPABILITY_CODE_ENHE);
- stream_putc (s, CAPABILITY_CODE_ENHE_LEN);
- /* Currently supporting for SAFI_UNICAST only */
- SET_FLAG (peer->af_cap[AFI_IP][SAFI_UNICAST], PEER_CAP_ENHE_AF_ADV);
- stream_putw (s, AFI_IP);
- stream_putw (s, SAFI_UNICAST);
- stream_putw (s, AFI_IP6);
-
- 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);
- }
-
/* Route refresh. */
SET_FLAG (peer->cap, PEER_CAP_REFRESH_ADV);
stream_putc (s, BGP_OPEN_OPT_CAP);