/* BGP attributes management routines.
- Copyright (C) 1996, 97, 98, 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) 1996, 97, 98, 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>
#if ENABLE_BGP_VNC
{ BGP_ATTR_VNC, "VNC" },
#endif
- { BGP_ATTR_LARGE_COMMUNITIES, "LARGE_COMMUNITY" }
+ { BGP_ATTR_LARGE_COMMUNITIES, "LARGE_COMMUNITY" },
+ { BGP_ATTR_PREFIX_SID, "PREFIX_SID" }
};
static const int attr_str_max = array_size(attr_str);
static struct attr_extra *
bgp_attr_extra_new (void)
{
- return XCALLOC (MTYPE_ATTR_EXTRA, sizeof (struct attr_extra));
+ struct attr_extra *extra;
+ extra = XCALLOC (MTYPE_ATTR_EXTRA, sizeof (struct attr_extra));
+ extra->label_index = BGP_INVALID_LABEL_INDEX;
+ return extra;
}
void
MIX(extra->mp_nexthop_global_in.s_addr);
MIX(extra->originator_id.s_addr);
MIX(extra->tag);
+ MIX(extra->label_index);
}
if (attr->aspath)
&& ae1->aggregator_addr.s_addr == ae2->aggregator_addr.s_addr
&& ae1->weight == ae2->weight
&& ae1->tag == ae2->tag
+ && ae1->label_index == ae2->label_index
&& ae1->mp_nexthop_len == ae2->mp_nexthop_len
&& IPV6_ADDR_SAME (&ae1->mp_nexthop_global, &ae2->mp_nexthop_global)
&& IPV6_ADDR_SAME (&ae1->mp_nexthop_local, &ae2->mp_nexthop_local)
return attr;
}
-
-/* Make network statement's attribute. */
-struct attr *
-bgp_attr_default_intern (u_char origin)
-{
- struct attr attr;
- struct attr *new;
-
- memset (&attr, 0, sizeof (struct attr));
- bgp_attr_extra_get (&attr);
-
- bgp_attr_default_set(&attr, origin);
-
- new = bgp_attr_intern (&attr);
- bgp_attr_extra_free (&attr);
-
- aspath_unintern (&new->aspath);
- return new;
-}
-
/* Create the attributes for an aggregate */
struct attr *
bgp_attr_aggregate_intern (struct bgp *bgp, u_char origin,
[BGP_ATTR_AS4_PATH] = BGP_ATTR_FLAG_OPTIONAL | BGP_ATTR_FLAG_TRANS,
[BGP_ATTR_AS4_AGGREGATOR] = BGP_ATTR_FLAG_OPTIONAL | BGP_ATTR_FLAG_TRANS,
[BGP_ATTR_LARGE_COMMUNITIES]= BGP_ATTR_FLAG_OPTIONAL | BGP_ATTR_FLAG_TRANS,
+ [BGP_ATTR_PREFIX_SID] = BGP_ATTR_FLAG_OPTIONAL | BGP_ATTR_FLAG_TRANS,
};
static const size_t attr_flags_values_max = array_size(attr_flags_values) - 1;
}
/* Set aspath attribute flag. */
- if (as4_path)
- attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_AS4_PATH);
+ attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_AS4_PATH);
return BGP_ATTR_PARSE_PROCEED;
}
return 0;
}
+/* Prefix SID attribute
+ * draft-ietf-idr-bgp-prefix-sid-05
+ */
+static bgp_attr_parse_ret_t
+bgp_attr_prefix_sid (struct bgp_attr_parser_args *args, struct bgp_nlri *mp_update)
+{
+ struct peer *const peer = args->peer;
+ struct attr *const attr = args->attr;
+ int type;
+ int length;
+ u_int32_t label_index;
+ struct in6_addr ipv6_sid;
+ u_int32_t srgb_base;
+ u_int32_t srgb_range;
+ int srgb_count;
+
+ attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_PREFIX_SID);
+
+ type = stream_getc (peer->ibuf);
+ length = stream_getw (peer->ibuf);
+
+ if (type == BGP_PREFIX_SID_LABEL_INDEX)
+ {
+ if (length != BGP_PREFIX_SID_LABEL_INDEX_LENGTH)
+ {
+ zlog_err ("Prefix SID label index length is %d instead of %d", length, BGP_PREFIX_SID_LABEL_INDEX_LENGTH);
+ return bgp_attr_malformed (args,
+ BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
+ args->total);
+ }
+
+ /* Ignore flags and reserved */
+ stream_getc (peer->ibuf);
+ stream_getw (peer->ibuf);
+
+ /* Fetch the label index and see if it is valid. */
+ label_index = stream_getl (peer->ibuf);
+ if (label_index == BGP_INVALID_LABEL_INDEX)
+ return bgp_attr_malformed (args,
+ BGP_NOTIFY_UPDATE_OPT_ATTR_ERR,
+ args->total);
+
+ /* Store label index; subsequently, we'll check on address-family */
+ (bgp_attr_extra_get (attr))->label_index = label_index;
+
+ /*
+ * Ignore the Label index attribute unless received for labeled-unicast
+ * SAFI.
+ */
+ if (!mp_update->length || mp_update->safi != SAFI_LABELED_UNICAST)
+ attr->extra->label_index = BGP_INVALID_LABEL_INDEX;
+ }
+
+ /* Placeholder code for the IPv6 SID type */
+ else if (type == BGP_PREFIX_SID_IPV6)
+ {
+ if (length != BGP_PREFIX_SID_IPV6_LENGTH)
+ {
+ zlog_err ("Prefix SID IPv6 length is %d instead of %d", length, BGP_PREFIX_SID_IPV6_LENGTH);
+ return bgp_attr_malformed (args,
+ BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
+ args->total);
+ }
+
+ /* Ignore reserved */
+ stream_getc (peer->ibuf);
+ stream_getw (peer->ibuf);
+
+ stream_get (&ipv6_sid, peer->ibuf, 16);
+ }
+
+ /* Placeholder code for the Originator SRGB type */
+ else if (type == BGP_PREFIX_SID_ORIGINATOR_SRGB)
+ {
+ /* Ignore flags */
+ stream_getw (peer->ibuf);
+
+ length -= 2;
+
+ if (length % BGP_PREFIX_SID_ORIGINATOR_SRGB_LENGTH)
+ {
+ zlog_err ("Prefix SID Originator SRGB length is %d, it must be a multiple of %d ",
+ length, BGP_PREFIX_SID_ORIGINATOR_SRGB_LENGTH);
+ return bgp_attr_malformed (args,
+ BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
+ args->total);
+ }
+
+ srgb_count = length / BGP_PREFIX_SID_ORIGINATOR_SRGB_LENGTH;
+
+ for (int i = 0; i < srgb_count; i++)
+ {
+ stream_get (&srgb_base, peer->ibuf, 3);
+ stream_get (&srgb_range, peer->ibuf, 3);
+ }
+ }
+
+ return BGP_ATTR_PARSE_PROCEED;
+}
+
/* BGP unknown attribute treatment. */
static bgp_attr_parse_ret_t
bgp_attr_unknown (struct bgp_attr_parser_args *args)
case BGP_ATTR_ENCAP:
ret = bgp_attr_encap (type, peer, length, attr, flag, startp);
break;
+ case BGP_ATTR_PREFIX_SID:
+ ret = bgp_attr_prefix_sid (&attr_args, mp_update);
+ break;
default:
ret = bgp_attr_unknown (&attr_args);
break;
}
size_t
-bgp_packet_mpattr_start (struct stream *s, afi_t afi, safi_t safi, afi_t nh_afi,
+bgp_packet_mpattr_start (struct stream *s, struct peer *peer,
+ afi_t afi, safi_t safi,
struct bpacket_attr_vec_arr *vecarr,
struct attr *attr)
{
size_t sizep;
iana_afi_t pkt_afi;
safi_t pkt_safi;
+ afi_t nh_afi;
/* Set extended bit always to encode the attribute length as 2 bytes */
stream_putc (s, BGP_ATTR_FLAG_OPTIONAL|BGP_ATTR_FLAG_EXTLEN);
stream_putw (s, pkt_afi); /* AFI */
stream_putc (s, pkt_safi); /* SAFI */
- if (afi == AFI_L2VPN)
- nh_afi = AFI_L2VPN;
- else if (nh_afi == AFI_MAX)
- nh_afi = BGP_NEXTHOP_AFI_FROM_NHLEN(attr->extra->mp_nexthop_len);
+
+ /* Nexthop AFI */
+ if (peer_cap_enhe(peer, afi, safi)) {
+ nh_afi = AFI_IP6;
+ } else {
+ if (afi == AFI_L2VPN)
+ nh_afi = AFI_L2VPN;
+ else if (safi == SAFI_LABELED_UNICAST)
+ nh_afi = afi;
+ else
+ nh_afi = BGP_NEXTHOP_AFI_FROM_NHLEN(attr->extra->mp_nexthop_len);
+ }
+
/* Nexthop */
switch (nh_afi)
{
{
case SAFI_UNICAST:
case SAFI_MULTICAST:
+ case SAFI_LABELED_UNICAST:
bpacket_attr_vec_arr_set_vec (vecarr, BGP_ATTR_VEC_NH, s, attr);
stream_putc (s, 4);
stream_put_ipv4 (s, attr->nexthop.s_addr);
{
case SAFI_UNICAST:
case SAFI_MULTICAST:
+ case SAFI_LABELED_UNICAST:
{
struct attr_extra *attre = attr->extra;
assert (attr->extra);
bpacket_attr_vec_arr_set_vec (vecarr, BGP_ATTR_VEC_NH, s, attr);
- stream_putc (s, attre->mp_nexthop_len);
- stream_put (s, &attre->mp_nexthop_global, IPV6_MAX_BYTELEN);
- if (attre->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL)
+
+ if (attre->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL) {
+ stream_putc (s, BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL);
+ stream_put (s, &attre->mp_nexthop_global, IPV6_MAX_BYTELEN);
stream_put (s, &attre->mp_nexthop_local, IPV6_MAX_BYTELEN);
+ } else {
+ stream_putc (s, IPV6_MAX_BYTELEN);
+ stream_put (s, &attre->mp_nexthop_global, IPV6_MAX_BYTELEN);
+ }
}
break;
case SAFI_MPLS_VPN:
{
bgp_packet_mpattr_route_type_5(s, p, prd, tag, attr);
}
+ else if (safi == SAFI_LABELED_UNICAST)
+ {
+ /* Prefix write with label. */
+ stream_put_labeled_prefix(s, p, tag);
+ }
else
stream_put_prefix_addpath (s, p, addpath_encode, addpath_tx_id);
}
case BGP_ATTR_ENCAP:
attrname = "Tunnel Encap";
subtlvs = attr->extra->encap_subtlvs;
-
+ if (subtlvs == NULL) /* nothing to do */
+ return;
/*
* The tunnel encap attr has an "outer" tlv.
* T = tunneltype,
case BGP_ATTR_VNC:
attrname = "VNC";
subtlvs = attr->extra->vnc_subtlvs;
+ if (subtlvs == NULL) /* nothing to do */
+ return;
attrlenfield = 0; /* no outer T + L */
attrhdrlen = 2 + 2; /* subTLV T + L */
break;
cp = stream_get_endp (s);
if (p && !((afi == AFI_IP && safi == SAFI_UNICAST) &&
- !peer_cap_enhe(peer)))
+ !peer_cap_enhe(peer, afi, safi)))
{
size_t mpattrlen_pos = 0;
- mpattrlen_pos = bgp_packet_mpattr_start(s, afi, safi,
- (peer_cap_enhe(peer) ? AFI_IP6 :
- AFI_MAX), /* get from NH */
- vecarr, attr);
+ mpattrlen_pos = bgp_packet_mpattr_start(s, peer, afi, safi, vecarr, attr);
bgp_packet_mpattr_prefix(s, afi, safi, p, prd, tag,
addpath_encode, addpath_tx_id, attr);
bgp_packet_mpattr_end(s, mpattrlen_pos);
send_as4_path = 1; /* we'll do this later, at the correct place */
/* Nexthop attribute. */
- if (afi == AFI_IP && safi == SAFI_UNICAST && !peer_cap_enhe(peer))
+ if (afi == AFI_IP && safi == SAFI_UNICAST && !peer_cap_enhe(peer, afi, safi))
{
if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP))
{
stream_putc (s, 4);
stream_put_ipv4 (s, attr->nexthop.s_addr);
}
- else if (safi == SAFI_UNICAST && peer_cap_enhe(from))
+ else if (peer_cap_enhe(from, afi, safi))
{
/*
* Likely this is the case when an IPv4 prefix was received with
}
}
+ /* Label index attribute. */
+ if (safi == SAFI_LABELED_UNICAST)
+ {
+ if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_PREFIX_SID))
+ {
+ u_int32_t label_index;
+
+ assert (attr->extra);
+ label_index = attr->extra->label_index;
+
+ if (label_index != BGP_INVALID_LABEL_INDEX)
+ {
+ stream_putc (s, BGP_ATTR_FLAG_OPTIONAL|BGP_ATTR_FLAG_TRANS);
+ stream_putc (s, BGP_ATTR_PREFIX_SID);
+ stream_putc (s, 10);
+ stream_putc (s, BGP_PREFIX_SID_LABEL_INDEX);
+ stream_putw (s, BGP_PREFIX_SID_LABEL_INDEX_LENGTH);
+ stream_putc (s, 0); // reserved
+ stream_putw (s, 0); // flags
+ stream_putl (s, label_index);
+ }
+ }
+ }
+
if ( send_as4_path )
{
/* If the peer is NOT As4 capable, AND */
u_char *tag, int addpath_encode,
u_int32_t addpath_tx_id, struct attr *attr)
{
+ u_char wlabel[3] = {0x80, 0x00, 0x00};
+
+ if (safi == SAFI_LABELED_UNICAST)
+ tag = wlabel;
+
return bgp_packet_mpattr_prefix (s, afi, safi, p, prd,
tag, addpath_encode, addpath_tx_id, attr);
}
stream_putc_at (s, sizep, (stream_get_endp (s) - sizep) - 1);
}
+ /* Prefix SID */
+ if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_PREFIX_SID))
+ {
+ assert (attr->extra);
+
+ if (attr->extra->label_index != BGP_INVALID_LABEL_INDEX)
+ {
+ stream_putc (s, BGP_ATTR_FLAG_OPTIONAL|BGP_ATTR_FLAG_TRANS);
+ stream_putc (s, BGP_ATTR_PREFIX_SID);
+ stream_putc (s, 10);
+ stream_putc (s, BGP_PREFIX_SID_LABEL_INDEX);
+ stream_putc (s, BGP_PREFIX_SID_LABEL_INDEX_LENGTH);
+ stream_putc (s, 0); // reserved
+ stream_putw (s, 0); // flags
+ stream_putl (s, attr->extra->label_index);
+ }
+ }
+
/* Return total size of attribute. */
len = stream_get_endp (s) - cp - 2;
stream_putw_at (s, cp, len);
/* BGP routing information
- Copyright (C) 1996, 97, 98, 99 Kunihiro Ishiguro
- Copyright (C) 2016 Job Snijders <job@instituut.net>
-
-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) 1996, 97, 98, 99 Kunihiro Ishiguro
+ * Copyright (C) 2016 Job Snijders <job@instituut.net>
+ *
+ * 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>
#include "thread.h"
#include "workqueue.h"
#include "queue.h"
+#include "mpls.h"
#include "memory.h"
#include "lib/json.h"
#include "bgpd/bgp_mpath.h"
#include "bgpd/bgp_nht.h"
#include "bgpd/bgp_updgrp.h"
+#include "bgpd/bgp_label.h"
#if ENABLE_BGP_VNC
#include "bgpd/rfapi/rfapi_backend.h"
}
}
+static int
+bgp_label_index_differs (struct bgp_info *ri1, struct bgp_info *ri2)
+{
+ return (!(ri1->attr->extra->label_index == ri2->attr->extra->label_index));
+}
/* Set/unset bgp_info flags, adjusting any other state as needed.
* This is here primarily to keep prefix-count in check.
}
int
-subgroup_announce_check (struct bgp_info *ri, struct update_subgroup *subgrp,
+subgroup_announce_check (struct bgp_node *rn, struct bgp_info *ri,
+ struct update_subgroup *subgrp,
struct prefix *p, struct attr *attr)
{
struct bgp_filter *filter;
return 0;
}
+ /* If it's labeled safi, make sure the route has a valid label. */
+ if (safi == SAFI_LABELED_UNICAST)
+ {
+ u_char *tag = bgp_adv_label(rn, ri, peer, afi, safi);
+ if (!bgp_is_valid_label(tag))
+ {
+ if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
+ zlog_debug ("u%" PRIu64 ":s%" PRIu64 " %s/%d is filtered - no label (%p)",
+ subgrp->update_group->id, subgrp->id,
+ inet_ntop(p->family, &p->u.prefix, buf, SU_ADDRSTRLEN),
+ p->prefixlen, tag);
+ return 0;
+ }
+ }
+
/* Do not send back route to sender. */
if (onlypeer && from == onlypeer)
{
#define NEXTHOP_IS_V6 (\
(safi != SAFI_ENCAP && safi != SAFI_MPLS_VPN &&\
- (p->family == AF_INET6 || peer_cap_enhe(peer))) || \
+ (p->family == AF_INET6 || peer_cap_enhe(peer, AFI_IP6, safi))) || \
((safi == SAFI_ENCAP || safi == SAFI_MPLS_VPN) &&\
attr->extra->mp_nexthop_len >= IPV6_MAX_BYTELEN))
if (!reflect ||
CHECK_FLAG (peer->af_flags[afi][safi],
PEER_FLAG_FORCE_NEXTHOP_SELF))
- subgroup_announce_reset_nhop ((peer_cap_enhe(peer) ?
+ subgroup_announce_reset_nhop ((peer_cap_enhe(peer, afi, safi) ?
AF_INET6 : p->family), attr);
}
else if (peer->sort == BGP_PEER_EBGP)
break;
}
if (!paf)
- subgroup_announce_reset_nhop ((peer_cap_enhe(peer) ? AF_INET6 : p->family), attr);
+ subgroup_announce_reset_nhop ((peer_cap_enhe(peer, afi, safi) ? AF_INET6 : p->family), attr);
}
/* If IPv6/MP and nexthop does not have any override and happens to
* be a link-local address, reset it so that we don't pass along the
* source's link-local IPv6 address to recipients who may not be on
* the same interface.
*/
- if (p->family == AF_INET6 || peer_cap_enhe(peer))
+ if (p->family == AF_INET6 || peer_cap_enhe(peer, afi, safi))
{
if (IN6_IS_ADDR_LINKLOCAL (&attr->extra->mp_nexthop_global))
subgroup_announce_reset_nhop (AF_INET6, attr);
/* Announcement to the subgroup. If the route is filtered withdraw it. */
if (selected)
{
- if (subgroup_announce_check(selected, subgrp, p, &attr))
+ if (subgroup_announce_check(rn, selected, subgrp, p, &attr))
bgp_adj_out_set_subgroup(rn, subgrp, &attr, selected);
else
bgp_adj_out_unset_subgroup(rn, subgrp, 1, selected->addpath_tx_id);
old_select = old_and_new.old;
new_select = old_and_new.new;
- /* Nothing to do. */
+ /* Do we need to allocate or free labels?
+ * Right now, since we only deal with per-prefix labels, it is not necessary
+ * to do this upon changes to best path except of the label index changes.
+ */
+ if (safi == SAFI_LABELED_UNICAST)
+ {
+ bgp_table_lock (bgp_node_table (rn));
+ if (new_select)
+ {
+ if (!old_select ||
+ bgp_label_index_differs (new_select, old_select) ||
+ new_select->sub_type != old_select->sub_type)
+ {
+ if (new_select->sub_type == BGP_ROUTE_STATIC &&
+ new_select->attr->flag & ATTR_FLAG_BIT (BGP_ATTR_PREFIX_SID) &&
+ new_select->attr->extra->label_index != BGP_INVALID_LABEL_INDEX)
+ {
+ if (CHECK_FLAG (rn->flags, BGP_NODE_REGISTERED_FOR_LABEL))
+ bgp_unregister_for_label (rn);
+ label_ntop (MPLS_IMP_NULL_LABEL, 1, rn->local_label);
+ bgp_set_valid_label(rn->local_label);
+ }
+ else
+ bgp_register_for_label (rn, new_select);
+ }
+ }
+ else if (CHECK_FLAG (rn->flags, BGP_NODE_REGISTERED_FOR_LABEL))
+ bgp_unregister_for_label (rn);
+ }
+
+ /* If best route remains the same and this is not due to user-initiated
+ * clear, see exactly what needs to be done.
+ */
+
if (old_select && old_select == new_select &&
!CHECK_FLAG(rn->flags, BGP_NODE_USER_CLEAR) &&
!CHECK_FLAG(old_select->flags, BGP_INFO_ATTR_CHANGED) &&
vnc_import_bgp_add_route(bgp, p, old_select);
vnc_import_bgp_exterior_add_route(bgp, p, old_select);
#endif
- bgp_zebra_announce (p, old_select, bgp, afi, safi);
+ if (bgp_fibupd_safi(safi) &&
+ !bgp->name &&
+ !bgp_option_check (BGP_OPT_NO_FIB) &&
+ new_select->type == ZEBRA_ROUTE_BGP &&
+ new_select->sub_type == BGP_ROUTE_NORMAL)
+ bgp_zebra_announce (rn, p, old_select, bgp, afi, safi);
}
UNSET_FLAG (old_select->flags, BGP_INFO_MULTIPATH_CHG);
bgp_zebra_clear_route_change_flags (rn);
+
+ /* If there is a change of interest to peers, reannounce the route. */
+ if (CHECK_FLAG (old_select->flags, BGP_INFO_ATTR_CHANGED) ||
+ CHECK_FLAG (rn->flags, BGP_NODE_LABEL_CHANGED))
+ {
+ group_announce_route(bgp, afi, safi, rn, new_select);
+
+ UNSET_FLAG (old_select->flags, BGP_INFO_ATTR_CHANGED);
+ UNSET_FLAG (rn->flags, BGP_NODE_LABEL_CHANGED);
+ }
+
UNSET_FLAG (rn->flags, BGP_NODE_PROCESS_SCHEDULED);
return WQ_SUCCESS;
}
if (!bgp->t_rmap_def_originate_eval)
{
bgp_lock (bgp);
- THREAD_TIMER_ON(bm->master, bgp->t_rmap_def_originate_eval,
- update_group_refresh_default_originate_route_map,
- bgp, RMAP_DEFAULT_ORIGINATE_EVAL_TIMER);
+ thread_add_timer(bm->master,
+ update_group_refresh_default_originate_route_map,
+ bgp, RMAP_DEFAULT_ORIGINATE_EVAL_TIMER,
+ &bgp->t_rmap_def_originate_eval);
}
}
group_announce_route(bgp, afi, safi, rn, new_select);
/* FIB update. */
- if ((safi == SAFI_UNICAST || safi == SAFI_MULTICAST) &&
+ if (bgp_fibupd_safi(safi) &&
(bgp->inst_type != BGP_INSTANCE_TYPE_VIEW) &&
!bgp_option_check (BGP_OPT_NO_FIB))
{
&& new_select->type == ZEBRA_ROUTE_BGP
&& (new_select->sub_type == BGP_ROUTE_NORMAL ||
new_select->sub_type == BGP_ROUTE_AGGREGATE))
- bgp_zebra_announce (p, new_select, bgp, afi, safi);
+ bgp_zebra_announce (rn, p, new_select, bgp, afi, safi);
else
{
/* Withdraw the route from the kernel. */
struct bgp_info *new;
const char *reason;
char pfx_buf[BGP_PRD_PATH_STRLEN];
+ char label_buf[20];
int connected = 0;
int do_loop_check = 1;
#if ENABLE_BGP_VNC
bgp = peer->bgp;
rn = bgp_afi_node_get (bgp->rib[afi][safi], afi, safi, p, prd);
+ label_buf[0] = '\0';
+ if (bgp_labeled_safi(safi))
+ sprintf (label_buf, "label %u", label_pton(tag));
/* When peer's soft reconfiguration enabled. Record input packet in
Adj-RIBs-In. */
/* Same attribute comes in. */
if (!CHECK_FLAG (ri->flags, BGP_INFO_REMOVED)
&& attrhash_cmp (ri->attr, attr_new)
+ && (!bgp_labeled_safi(safi) ||
+ memcmp ((bgp_info_extra_get (ri))->tag, tag, 3) == 0)
&& (overlay_index_equal(afi, ri, evpn==NULL?NULL:&evpn->eth_s_id,
evpn==NULL?NULL:&evpn->gw_ip)))
{
&& CHECK_FLAG (ri->flags, BGP_INFO_HISTORY))
{
if (bgp_debug_update(peer, p, NULL, 1))
- zlog_debug ("%s rcvd %s", peer->host,
+ zlog_debug ("%s rcvd %s %s", peer->host,
bgp_debug_rdpfxpath2str (prd, p, addpath_id ? 1 : 0,
- addpath_id, pfx_buf, sizeof (pfx_buf)));
+ addpath_id, pfx_buf, sizeof (pfx_buf)), label_buf);
if (bgp_damp_update (ri, rn, afi, safi) != BGP_DAMP_SUPPRESSED)
{
peer->rcvd_attr_printed = 1;
}
- zlog_debug ("%s rcvd %s...duplicate ignored",
+ zlog_debug ("%s rcvd %s %s...duplicate ignored",
peer->host,
bgp_debug_rdpfxpath2str (prd, p, addpath_id ?
- 1 : 0, addpath_id, pfx_buf, sizeof (pfx_buf)));
+ 1 : 0, addpath_id, pfx_buf, sizeof (pfx_buf)), label_buf);
}
/* graceful restart STALE flag unset. */
if (CHECK_FLAG(ri->flags, BGP_INFO_REMOVED))
{
if (bgp_debug_update(peer, p, NULL, 1))
- zlog_debug ("%s rcvd %s, flapped quicker than processing",
+ zlog_debug ("%s rcvd %s %s, flapped quicker than processing",
peer->host,
bgp_debug_rdpfxpath2str (prd, p, addpath_id ? 1 : 0,
- addpath_id, pfx_buf, sizeof (pfx_buf)));
+ addpath_id, pfx_buf, sizeof (pfx_buf)), label_buf);
bgp_info_restore (rn, ri);
}
/* Received Logging. */
if (bgp_debug_update(peer, p, NULL, 1))
- zlog_debug ("%s rcvd %s", peer->host,
+ zlog_debug ("%s rcvd %s %s", peer->host,
bgp_debug_rdpfxpath2str (prd, p, addpath_id ? 1 : 0,
- addpath_id, pfx_buf, sizeof (pfx_buf)));
+ addpath_id, pfx_buf, sizeof (pfx_buf)), label_buf);
/* graceful restart STALE flag unset. */
if (CHECK_FLAG (ri->flags, BGP_INFO_STALE))
ri->attr = attr_new;
/* Update MPLS tag. */
- if (safi == SAFI_MPLS_VPN || safi == SAFI_EVPN)
+ if (bgp_labeled_safi(safi))
memcpy ((bgp_info_extra_get (ri))->tag, tag, 3);
#if ENABLE_BGP_VNC
}
}
- /* Nexthop reachability check. */
- if ((afi == AFI_IP || afi == AFI_IP6) && safi == SAFI_UNICAST)
+ /* Nexthop reachability check - for unicast and labeled-unicast.. */
+ if ((afi == AFI_IP || afi == AFI_IP6) &&
+ (safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST))
{
if (peer->sort == BGP_PEER_EBGP && peer->ttl == 1 &&
! CHECK_FLAG (peer->flags, PEER_FLAG_DISABLE_CONNECTED_CHECK)
peer->rcvd_attr_printed = 1;
}
- zlog_debug ("%s rcvd %s", peer->host,
+ zlog_debug ("%s rcvd %s%s ", peer->host,
bgp_debug_rdpfxpath2str (prd, p, addpath_id ? 1 : 0,
- addpath_id, pfx_buf, sizeof (pfx_buf)));
+ addpath_id, pfx_buf, sizeof (pfx_buf)), label_buf);
}
/* Make new BGP info. */
new = info_make(type, sub_type, 0, peer, attr_new, rn);
/* Update MPLS tag. */
- if (safi == SAFI_MPLS_VPN || safi == SAFI_EVPN)
+ if (bgp_labeled_safi(safi))
memcpy ((bgp_info_extra_get (new))->tag, tag, 3);
/* Update Overlay Index */
evpn==NULL?NULL:&evpn->gw_ip);
}
/* Nexthop reachability check. */
- if ((afi == AFI_IP || afi == AFI_IP6) && safi == SAFI_UNICAST)
+ if ((afi == AFI_IP || afi == AFI_IP6) &&
+ (safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST))
{
if (peer->sort == BGP_PEER_EBGP && peer->ttl == 1 &&
! CHECK_FLAG (peer->flags, PEER_FLAG_DISABLE_CONNECTED_CHECK)
peer->rcvd_attr_printed = 1;
}
- zlog_debug ("%s rcvd UPDATE about %s -- DENIED due to: %s",
+ zlog_debug ("%s rcvd UPDATE about %s %s -- DENIED due to: %s",
peer->host,
bgp_debug_rdpfxpath2str (prd, p, addpath_id ? 1 : 0,
- addpath_id, pfx_buf, sizeof (pfx_buf)), reason);
+ addpath_id, pfx_buf, sizeof (pfx_buf)), label_buf, reason);
}
if (ri)
paf = THREAD_ARG (t);
peer = paf->peer;
- assert (paf->t_announce_route);
- paf->t_announce_route = NULL;
-
if (peer->status != Established)
return 0;
* multiple peers and the announcement doesn't happen in the
* vty context.
*/
- THREAD_TIMER_MSEC_ON (bm->master, paf->t_announce_route,
- bgp_announce_route_timer_expired, paf,
- (subgrp->peer_count == 1) ?
- BGP_ANNOUNCE_ROUTE_SHORT_DELAY_MS :
- BGP_ANNOUNCE_ROUTE_DELAY_MS);
+ thread_add_timer_msec(bm->master, bgp_announce_route_timer_expired, paf,
+ (subgrp->peer_count == 1) ? BGP_ANNOUNCE_ROUTE_SHORT_DELAY_MS : BGP_ANNOUNCE_ROUTE_DELAY_MS,
+ &paf->t_announce_route);
}
/*
XFREE (MTYPE_BGP_STATIC, bgp_static);
}
-static void
-bgp_static_update_main (struct bgp *bgp, struct prefix *p,
- struct bgp_static *bgp_static, afi_t afi, safi_t safi)
+void
+bgp_static_update (struct bgp *bgp, struct prefix *p,
+ struct bgp_static *bgp_static, afi_t afi, safi_t safi)
{
struct bgp_node *rn;
struct bgp_info *ri;
if (bgp_static->atomic)
attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_ATOMIC_AGGREGATE);
+ /* Store label index, if required. */
+ if (bgp_static->label_index != BGP_INVALID_LABEL_INDEX)
+ {
+ (bgp_attr_extra_get (&attr))->label_index = bgp_static->label_index;
+ attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_PREFIX_SID);
+ }
+
/* Apply route-map. */
if (bgp_static->rmap.name)
{
#endif
/* Nexthop reachability check. */
- if (bgp_flag_check (bgp, BGP_FLAG_IMPORT_CHECK))
+ if (bgp_flag_check (bgp, BGP_FLAG_IMPORT_CHECK) &&
+ safi == SAFI_UNICAST)
{
- if (bgp_find_or_add_nexthop (bgp, afi, ri, NULL, 0))
+ if (bgp_find_or_add_nexthop (bgp, afi, ri, NULL, 0) &&
+ safi == SAFI_UNICAST)
bgp_info_set_flag (rn, ri, BGP_INFO_VALID);
else
{
bgp_attr_extra_free (&attr);
}
-void
-bgp_static_update (struct bgp *bgp, struct prefix *p,
- struct bgp_static *bgp_static, afi_t afi, safi_t safi)
-{
- bgp_static_update_main (bgp, p, bgp_static, afi, safi);
-}
-
void
bgp_static_withdraw (struct bgp *bgp, struct prefix *p, afi_t afi,
safi_t safi)
if ((safi == SAFI_EVPN) || (safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP))
{
- if (bgp_static->igpnexthop.s_addr)
+ if (afi == AFI_IP)
{
bgp_attr_extra_get (&attr)->mp_nexthop_global_in = bgp_static->igpnexthop;
bgp_attr_extra_get (&attr)->mp_nexthop_len = IPV4_MAX_BYTELEN;
route should be installed as valid. */
static int
bgp_static_set (struct vty *vty, const char *ip_str,
- afi_t afi, safi_t safi, const char *rmap, int backdoor)
+ afi_t afi, safi_t safi, const char *rmap, int backdoor,
+ u_int32_t label_index)
{
VTY_DECLVAR_CONTEXT(bgp, bgp);
int ret;
/* Configuration change. */
bgp_static = rn->info;
+ /* Label index cannot be changed. */
+ if (bgp_static->label_index != label_index)
+ {
+ vty_out (vty, "%% Label index cannot be changed%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
/* Check previous routes are installed into BGP. */
if (bgp_static->valid && bgp_static->backdoor != backdoor)
need_update = 1;
bgp_static->valid = 0;
bgp_static->igpmetric = 0;
bgp_static->igpnexthop.s_addr = 0;
+ bgp_static->label_index = label_index;
if (rmap)
{
*/
int
bgp_static_set_safi (afi_t afi, safi_t safi, struct vty *vty, const char *ip_str,
- const char *rd_str, const char *tag_str,
+ const char *rd_str, const char *label_str,
const char *rmap_str, int evpn_type, const char *esi, const char *gwip,
const char *ethtag, const char *routermac)
{
return CMD_WARNING;
}
- if (tag_str)
+ if (label_str)
{
- ret = str2tag (tag_str, tag);
- if (! ret)
- {
- vty_out (vty, "%% Malformed tag%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
+ unsigned long label_val;
+ VTY_GET_INTEGER_RANGE("Label/tag", label_val, label_str, 0, 16777215);
+ encode_label (label_val, tag);
}
else
{
- encode_label (0, tag);
+ memset (tag, 0, sizeof(tag)); /* empty, not even BoS */
}
if (safi == SAFI_EVPN)
{
if (rmap_str)
{
if (bgp_static->rmap.name)
- free (bgp_static->rmap.name);
- bgp_static->rmap.name = strdup (rmap_str);
+ XFREE(MTYPE_ROUTE_MAP_NAME, bgp_static->rmap.name);
+ bgp_static->rmap.name = XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap_str);
bgp_static->rmap.map = route_map_lookup_by_name (rmap_str);
}
/* Configure static BGP network. */
int
bgp_static_unset_safi(afi_t afi, safi_t safi, struct vty *vty, const char *ip_str,
- const char *rd_str, const char *tag_str,
+ const char *rd_str, const char *label_str,
int evpn_type, const char *esi, const char *gwip, const char *ethtag)
{
VTY_DECLVAR_CONTEXT(bgp, bgp);
return CMD_WARNING;
}
- ret = str2tag (tag_str, tag);
- if (! ret)
+ if (label_str)
{
- vty_out (vty, "%% Malformed tag%s", VTY_NEWLINE);
- return CMD_WARNING;
+ unsigned long label_val;
+ VTY_GET_INTEGER_RANGE("Label/tag", label_val, label_str, 0, MPLS_LABEL_MAX);
+ encode_label (label_val, tag);
+ }
+ else
+ {
+ memset (tag, 0, sizeof(tag)); /* empty, not even BoS */
}
prn = bgp_node_get (bgp->route[afi][safi],
{
int idx_ipv4_prefixlen = 1;
return bgp_static_set (vty, argv[idx_ipv4_prefixlen]->arg,
- AFI_IP, bgp_node_safi (vty), NULL, 0);
+ AFI_IP, bgp_node_safi (vty), NULL, 0,
+ BGP_INVALID_LABEL_INDEX);
}
DEFUN (bgp_network_route_map,
int idx_ipv4_prefixlen = 1;
int idx_word = 3;
return bgp_static_set (vty, argv[idx_ipv4_prefixlen]->arg,
- AFI_IP, bgp_node_safi (vty), argv[idx_word]->arg, 0);
+ AFI_IP, bgp_node_safi (vty), argv[idx_word]->arg, 0,
+ BGP_INVALID_LABEL_INDEX);
}
DEFUN (bgp_network_backdoor,
{
int idx_ipv4_prefixlen = 1;
return bgp_static_set (vty, argv[idx_ipv4_prefixlen]->arg, AFI_IP, SAFI_UNICAST,
- NULL, 1);
+ NULL, 1, BGP_INVALID_LABEL_INDEX);
}
DEFUN (bgp_network_mask,
}
return bgp_static_set (vty, prefix_str,
- AFI_IP, bgp_node_safi (vty), NULL, 0);
+ AFI_IP, bgp_node_safi (vty), NULL, 0, BGP_INVALID_LABEL_INDEX);
}
DEFUN (bgp_network_mask_route_map,
}
return bgp_static_set (vty, prefix_str,
- AFI_IP, bgp_node_safi (vty), argv[idx_word]->arg, 0);
+ AFI_IP, bgp_node_safi (vty), argv[idx_word]->arg, 0, BGP_INVALID_LABEL_INDEX);
}
DEFUN (bgp_network_mask_backdoor,
}
return bgp_static_set (vty, prefix_str, AFI_IP, SAFI_UNICAST,
- NULL, 1);
+ NULL, 1,
+ BGP_INVALID_LABEL_INDEX);
}
DEFUN (bgp_network_mask_natural,
}
return bgp_static_set (vty, prefix_str,
- AFI_IP, bgp_node_safi (vty), NULL, 0);
+ AFI_IP, bgp_node_safi (vty), NULL, 0,
+ BGP_INVALID_LABEL_INDEX);
}
DEFUN (bgp_network_mask_natural_route_map,
}
return bgp_static_set (vty, prefix_str,
- AFI_IP, bgp_node_safi (vty), argv[idx_word]->arg, 0);
+ AFI_IP, bgp_node_safi (vty), argv[idx_word]->arg, 0,
+ BGP_INVALID_LABEL_INDEX);
}
DEFUN (bgp_network_mask_natural_backdoor,
}
return bgp_static_set (vty, prefix_str, AFI_IP, SAFI_UNICAST,
- NULL, 1);
+ NULL, 1, BGP_INVALID_LABEL_INDEX);
+}
+
+DEFUN (bgp_network_label_index,
+ bgp_network_label_index_cmd,
+ "network A.B.C.D/M label-index (0-4294967294)",
+ "Specify a network to announce via BGP\n"
+ "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
+ "Label index to associate with the prefix\n"
+ "Label index value\n")
+{
+ u_int32_t label_index;
+
+ VTY_GET_INTEGER ("label-index", label_index, argv[3]->arg);
+ return bgp_static_set (vty, argv[1]->arg,
+ AFI_IP, bgp_node_safi (vty), NULL, 0, label_index);
+}
+
+DEFUN (bgp_network_label_index_route_map,
+ bgp_network_label_index_route_map_cmd,
+ "network A.B.C.D/M label-index (0-4294967294) route-map WORD",
+ "Specify a network to announce via BGP\n"
+ "IP prefix\n"
+ "Label index to associate with the prefix\n"
+ "Label index value\n"
+ "Route-map to modify the attributes\n"
+ "Name of the route map\n")
+{
+ u_int32_t label_index;
+
+ VTY_GET_INTEGER ("label-index", label_index, argv[3]->arg);
+ return bgp_static_set (vty, argv[1]->arg,
+ AFI_IP, bgp_node_safi (vty), argv[5]->arg, 0, label_index);
}
DEFUN (no_bgp_network,
bgp_node_safi (vty));
}
+ALIAS (no_bgp_network,
+ no_bgp_network_label_index_cmd,
+ "no network A.B.C.D/M label-index (0-4294967294)",
+ NO_STR
+ "Specify a network to announce via BGP\n"
+ "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
+ "Label index to associate with the prefix\n"
+ "Label index value\n")
+
+ALIAS (no_bgp_network,
+ no_bgp_network_label_index_route_map_cmd,
+ "no network A.B.C.D/M label-index (0-4294967294) route-map WORD",
+ NO_STR
+ "Specify a network to announce via BGP\n"
+ "IP prefix\n"
+ "Label index to associate with the prefix\n"
+ "Label index value\n"
+ "Route-map to modify the attributes\n"
+ "Name of the route map\n")
+
DEFUN (ipv6_bgp_network,
ipv6_bgp_network_cmd,
"network X:X::X:X/M",
{
int idx_ipv6_prefixlen = 1;
return bgp_static_set (vty, argv[idx_ipv6_prefixlen]->arg, AFI_IP6, bgp_node_safi(vty),
- NULL, 0);
+ NULL, 0,
+ BGP_INVALID_LABEL_INDEX);
}
DEFUN (ipv6_bgp_network_route_map,
int idx_ipv6_prefixlen = 1;
int idx_word = 3;
return bgp_static_set (vty, argv[idx_ipv6_prefixlen]->arg, AFI_IP6,
- bgp_node_safi (vty), argv[idx_word]->arg, 0);
+ bgp_node_safi (vty), argv[idx_word]->arg, 0,
+ BGP_INVALID_LABEL_INDEX);
+}
+
+DEFUN (ipv6_bgp_network_label_index,
+ ipv6_bgp_network_label_index_cmd,
+ "network X:X::X:X/M label-index (0-4294967294)",
+ "Specify a network to announce via BGP\n"
+ "IPv6 prefix <network>/<length>\n"
+ "Label index to associate with the prefix\n"
+ "Label index value\n")
+{
+ u_int32_t label_index;
+
+ VTY_GET_INTEGER ("label-index", label_index, argv[3]->arg);
+ return bgp_static_set (vty, argv[1]->arg,
+ AFI_IP6, bgp_node_safi (vty), NULL, 0, label_index);
+}
+
+DEFUN (ipv6_bgp_network_label_index_route_map,
+ ipv6_bgp_network_label_index_route_map_cmd,
+ "network X:X::X:X/M label-index (0-4294967294) route-map WORD",
+ "Specify a network to announce via BGP\n"
+ "IPv6 prefix\n"
+ "Label index to associate with the prefix\n"
+ "Label index value\n"
+ "Route-map to modify the attributes\n"
+ "Name of the route map\n")
+{
+ u_int32_t label_index;
+
+ VTY_GET_INTEGER ("label-index", label_index, argv[3]->arg);
+ return bgp_static_set (vty, argv[1]->arg,
+ AFI_IP6, bgp_node_safi (vty), argv[5]->arg, 0, label_index);
}
DEFUN (no_ipv6_bgp_network,
return bgp_static_unset (vty, argv[idx_ipv6_prefixlen]->arg, AFI_IP6, bgp_node_safi(vty));
}
+ALIAS (no_ipv6_bgp_network,
+ no_ipv6_bgp_network_label_index_cmd,
+ "no network X:X::X:X/M label-index (0-4294967294)",
+ NO_STR
+ "Specify a network to announce via BGP\n"
+ "IPv6 prefix <network>/<length>\n"
+ "Label index to associate with the prefix\n"
+ "Label index value\n")
+
+ALIAS (no_ipv6_bgp_network,
+ no_ipv6_bgp_network_label_index_route_map_cmd,
+ "no network X:X::X:X/M label-index (0-4294967294) route-map WORD",
+ NO_STR
+ "Specify a network to announce via BGP\n"
+ "IPv6 prefix\n"
+ "Label index to associate with the prefix\n"
+ "Label index value\n"
+ "Route-map to modify the attributes\n"
+ "Name of the route map\n")
+
/* Aggreagete address:
advertise-map Set condition to advertise attribute
}
aggregate = rn->info;
- if (aggregate->safi & SAFI_UNICAST)
+ if (aggregate->safi == SAFI_UNICAST)
bgp_aggregate_delete (bgp, &p, afi, SAFI_UNICAST, aggregate);
- if (aggregate->safi & SAFI_MULTICAST)
+ if (aggregate->safi == SAFI_LABELED_UNICAST)
+ bgp_aggregate_delete (bgp, &p, afi, SAFI_LABELED_UNICAST, aggregate);
+ if (aggregate->safi == SAFI_MULTICAST)
bgp_aggregate_delete (bgp, &p, afi, SAFI_MULTICAST, aggregate);
/* Unlock aggregate address configuration. */
rn->info = aggregate;
/* Aggregate address insert into BGP routing table. */
- if (safi & SAFI_UNICAST)
+ if (safi == SAFI_UNICAST)
bgp_aggregate_add (bgp, &p, afi, SAFI_UNICAST, aggregate);
- if (safi & SAFI_MULTICAST)
+ if (safi == SAFI_LABELED_UNICAST)
+ bgp_aggregate_add (bgp, &p, afi, SAFI_LABELED_UNICAST, aggregate);
+ if (safi == SAFI_MULTICAST)
bgp_aggregate_add (bgp, &p, afi, SAFI_MULTICAST, aggregate);
return CMD_SUCCESS;
{
int idx = 0;
argv_find (argv, argc, "A.B.C.D", &idx);
- char *prefix = argv[idx++]->arg;
- argv_find (argv, argc, "A.B.C.D", &idx);
- char *mask = argv[idx]->arg;
+ char *prefix = argv[idx]->arg;
+ char *mask = argv[idx+1]->arg;
int as_set = argv_find (argv, argc, "as-set", &idx) ? AGGREGATE_AS_SET : 0;
idx = 0;
int summary_only = argv_find (argv, argc, "summary-only", &idx) ? AGGREGATE_SUMMARY_ONLY : 0;
{
int idx = 0;
argv_find (argv, argc, "A.B.C.D", &idx);
- char *prefix = argv[idx++]->arg;
- argv_find (argv, argc, "A.B.C.D", &idx);
- char *mask = argv[idx]->arg;
+ char *prefix = argv[idx]->arg;
+ char *mask = argv[idx+1]->arg;
char prefix_str[BUFSIZ];
int ret = netmask_str2prefix_str (prefix, mask, prefix_str);
if (binfo->extra && binfo->extra->damp_info)
bgp_damp_info_vty (vty, binfo, json_path);
+ /* Remove Label */
+ if (bgp_labeled_safi(safi) && binfo->extra)
+ {
+ uint32_t label = label_pton(binfo->extra->tag);
+ if (json_paths)
+ json_object_int_add(json_path, "remoteLabel", label);
+ else
+ vty_out(vty, " Remote label: %d%s", label, VTY_NEWLINE);
+ }
+
+ /* Label Index */
+ if (attr->extra->label_index != BGP_INVALID_LABEL_INDEX)
+ {
+ if (json_paths)
+ json_object_int_add(json_path, "labelIndex", attr->extra->label_index);
+ else
+ vty_out(vty, " Label Index: %d%s", attr->extra->label_index, VTY_NEWLINE);
+ }
+
/* Line 8 display Addpath IDs */
if (binfo->addpath_rx_id || binfo->addpath_tx_id)
{
((safi == SAFI_MPLS_VPN) || (safi == SAFI_EVPN)) ? ":" : "",
buf2,
p->prefixlen, VTY_NEWLINE);
+
+ if (bgp_labeled_safi(safi))
+ {
+ vty_out(vty, "Local label: ");
+ if (!bgp_is_valid_label(rn->local_label))
+ vty_out(vty, "not allocated%s", VTY_NEWLINE);
+ else
+ {
+ uint32_t label = label_pton(rn->local_label);
+ vty_out(vty, "%d%s", label, VTY_NEWLINE);
+ }
+ }
}
for (ri = rn->info; ri; ri = ri->next)
DEFUN (show_ip_bgp_large_community_list,
show_ip_bgp_large_community_list_cmd,
- "show [ip] bgp [<view|vrf> WORD] [<ipv4|ipv6> [<unicast|multicast|vpn|encap>]] large-community-list <(1-500)|WORD> [json]",
+ "show [ip] bgp [<view|vrf> WORD] [<ipv4|ipv6> [<unicast|multicast|vpn|encap|labeled-unicast>]] large-community-list <(1-500)|WORD> [json]",
SHOW_STR
IP_STR
BGP_STR
"Address Family modifier\n"
"Address Family modifier\n"
"Address Family modifier\n"
+ "Address Family modifier\n"
"Display routes matching the large-community-list\n"
"large-community-list number\n"
"large-community-list name\n"
}
DEFUN (show_ip_bgp_large_community,
show_ip_bgp_large_community_cmd,
- "show [ip] bgp [<view|vrf> WORD] [<ipv4|ipv6> [<unicast|multicast|vpn|encap>]] large-community [AA:BB:CC] [json]",
+ "show [ip] bgp [<view|vrf> WORD] [<ipv4|ipv6> [<unicast|multicast|vpn|encap|labeled-unicast>]] large-community [AA:BB:CC] [json]",
SHOW_STR
IP_STR
BGP_STR
"Address Family modifier\n"
"Address Family modifier\n"
"Address Family modifier\n"
+ "Address Family modifier\n"
"Display routes matching the large-communities\n"
"List of large-community numbers\n"
JSON_STR)
int i;
char *str;
int first = 0;
+ int ret = 0;
b = buffer_new (1024);
for (i = 0; i < argc; i++)
return CMD_WARNING;
}
- return bgp_show (vty, bgp, afi, safi,
- (exact ? bgp_show_type_community_exact :
- bgp_show_type_community), com, 0);
+ ret = bgp_show (vty, bgp, afi, safi,
+ (exact ? bgp_show_type_community_exact :
+ bgp_show_type_community), com, 0);
+ community_free (com);
+
+ return ret;
}
static int
DEFUN (show_ip_bgp_instance_neighbor_prefix_counts,
show_ip_bgp_instance_neighbor_prefix_counts_cmd,
- "show [ip] bgp [<view|vrf> WORD] [<ipv4|ipv6> [<unicast|multicast|vpn|encap>]] "
+ "show [ip] bgp [<view|vrf> WORD] [<ipv4|ipv6> [<unicast|multicast|vpn|encap|labeled-unicast>]] "
"neighbors <A.B.C.D|X:X::X:X|WORD> prefix-counts [json]",
SHOW_STR
IP_STR
"Address Family modifier\n"
"Address Family modifier\n"
"Address Family modifier\n"
+ "Address Family modifier\n"
"Detailed information on TCP and BGP neighbor connections\n"
"Neighbor to display information about\n"
"Neighbor to display information about\n"
prefix_rd2str (prd, rdbuf, RD_ADDRSTRLEN);
label = decode_label (bgp_static->tag);
- vty_out (vty, " network %s/%d rd %s tag %d",
+ vty_out (vty, " network %s/%d rd %s label %d",
inet_ntop (p->family, &p->u.prefix, buf, SU_ADDRSTRLEN),
p->prefixlen,
rdbuf, label);
+ if (bgp_static->rmap.name)
+ vty_out (vty, " route-map %s", bgp_static->rmap.name);
+ else
+ {
+ if (bgp_static->backdoor)
+ vty_out (vty, " backdoor");
+ }
vty_out (vty, "%s", VTY_NEWLINE);
}
return 0;
p->prefixlen);
}
+ if (bgp_static->label_index != BGP_INVALID_LABEL_INDEX)
+ vty_out (vty, " label-index %u", bgp_static->label_index);
+
if (bgp_static->rmap.name)
vty_out (vty, " route-map %s", bgp_static->rmap.name);
else
install_element (BGP_IPV4_NODE, &bgp_network_route_map_cmd);
install_element (BGP_IPV4_NODE, &bgp_network_mask_route_map_cmd);
install_element (BGP_IPV4_NODE, &bgp_network_mask_natural_route_map_cmd);
+ install_element (BGP_IPV4L_NODE, &no_bgp_network_label_index_cmd);
+ install_element (BGP_IPV4L_NODE, &no_bgp_network_label_index_route_map_cmd);
install_element (BGP_IPV4_NODE, &no_bgp_table_map_cmd);
install_element (BGP_IPV4_NODE, &no_bgp_network_cmd);
install_element (BGP_IPV4_NODE, &no_bgp_network_mask_cmd);
install_element (BGP_IPV4M_NODE, &no_aggregate_address_cmd);
install_element (BGP_IPV4M_NODE, &no_aggregate_address_mask_cmd);
+ /* IPv4 labeled-unicast configuration. */
+ install_element (BGP_IPV4L_NODE, &bgp_table_map_cmd);
+ install_element (BGP_IPV4L_NODE, &bgp_network_cmd);
+ install_element (BGP_IPV4L_NODE, &bgp_network_mask_cmd);
+ install_element (BGP_IPV4L_NODE, &bgp_network_mask_natural_cmd);
+ install_element (BGP_IPV4L_NODE, &bgp_network_route_map_cmd);
+ install_element (BGP_IPV4L_NODE, &bgp_network_mask_route_map_cmd);
+ install_element (BGP_IPV4L_NODE, &bgp_network_mask_natural_route_map_cmd);
+ install_element (BGP_IPV4L_NODE, &bgp_network_label_index_cmd);
+ install_element (BGP_IPV4L_NODE, &bgp_network_label_index_route_map_cmd);
+ install_element (BGP_IPV4L_NODE, &no_bgp_table_map_cmd);
+ install_element (BGP_IPV4L_NODE, &no_bgp_network_cmd);
+ install_element (BGP_IPV4L_NODE, &no_bgp_network_mask_cmd);
+ install_element (BGP_IPV4L_NODE, &no_bgp_network_mask_natural_cmd);
+
install_element (VIEW_NODE, &show_ip_bgp_instance_all_cmd);
install_element (VIEW_NODE, &show_ip_bgp_cmd);
install_element (VIEW_NODE, &show_ip_bgp_route_cmd);
install_element (BGP_IPV6_NODE, &ipv6_bgp_network_route_map_cmd);
install_element (BGP_IPV6_NODE, &no_bgp_table_map_cmd);
install_element (BGP_IPV6_NODE, &no_ipv6_bgp_network_cmd);
+ install_element (BGP_IPV6_NODE, &ipv6_bgp_network_label_index_cmd);
+ install_element (BGP_IPV6_NODE, &no_ipv6_bgp_network_label_index_cmd);
+ install_element (BGP_IPV6_NODE, &ipv6_bgp_network_label_index_route_map_cmd);
+ install_element (BGP_IPV6_NODE, &no_ipv6_bgp_network_label_index_route_map_cmd);
install_element (BGP_IPV6_NODE, &ipv6_aggregate_address_cmd);
install_element (BGP_IPV6_NODE, &no_ipv6_aggregate_address_cmd);
install_element (BGP_IPV6M_NODE, &ipv6_bgp_network_cmd);
install_element (BGP_IPV6M_NODE, &no_ipv6_bgp_network_cmd);
+ install_element (BGP_IPV6L_NODE, &bgp_table_map_cmd);
+ install_element (BGP_IPV6L_NODE, &ipv6_bgp_network_cmd);
+ install_element (BGP_IPV6L_NODE, &ipv6_bgp_network_route_map_cmd);
+ install_element (BGP_IPV6L_NODE, &no_bgp_table_map_cmd);
+ install_element (BGP_IPV6L_NODE, &no_ipv6_bgp_network_cmd);
+
install_element (BGP_NODE, &bgp_distance_cmd);
install_element (BGP_NODE, &no_bgp_distance_cmd);
install_element (BGP_NODE, &bgp_distance_source_cmd);