Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mpls #342

Closed
wants to merge 19 commits into from
Closed

Mpls #342

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions bgpd/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ libbgp_a_SOURCES = \
bgp_damp.c bgp_table.c bgp_advertise.c bgp_vty.c bgp_mpath.c \
bgp_nht.c bgp_updgrp.c bgp_updgrp_packet.c bgp_updgrp_adv.c bgp_bfd.c \
bgp_encap.c bgp_encap_tlv.c $(BGP_VNC_RFAPI_SRC) bgp_attr_evpn.c \
bgp_evpn.c bgp_evpn_vty.c bgp_vpn.c
bgp_evpn.c bgp_evpn_vty.c bgp_vpn.c bgp_label.c

noinst_HEADERS = \
bgp_memory.h \
Expand All @@ -92,7 +92,8 @@ noinst_HEADERS = \
bgp_mplsvpn.h bgp_nexthop.h bgp_damp.h bgp_table.h \
bgp_advertise.h bgp_vty.h bgp_mpath.h bgp_nht.h \
bgp_updgrp.h bgp_bfd.h bgp_encap.h bgp_encap_tlv.h bgp_encap_types.h \
$(BGP_VNC_RFAPI_HD) bgp_attr_evpn.h bgp_evpn.h bgp_evpn_vty.h bgp_vpn.h
$(BGP_VNC_RFAPI_HD) bgp_attr_evpn.h bgp_evpn.h bgp_evpn_vty.h \
bgp_vpn.h bgp_label.h

bgpd_SOURCES = bgp_main.c
bgpd_LDADD = libbgp.a $(BGP_VNC_RFP_LIB) ../lib/libfrr.la @LIBCAP@ @LIBM@
Expand Down
98 changes: 97 additions & 1 deletion bgpd/bgp_attr.c
Original file line number Diff line number Diff line change
Expand Up @@ -676,6 +676,7 @@ attrhash_key_make (void *p)
MIX(extra->mp_nexthop_global_in.s_addr);
MIX(extra->originator_id.s_addr);
MIX(extra->tag);
MIX(extra->label_index);
}

if (attr->aspath)
Expand Down Expand Up @@ -730,6 +731,7 @@ attrhash_cmp (const void *p1, const void *p2)
&& 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)
Expand Down Expand Up @@ -1287,6 +1289,7 @@ const u_int8_t attr_flags_values [] = {
[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_LABEL_INDEX] = BGP_ATTR_FLAG_OPTIONAL | BGP_ATTR_FLAG_TRANS,
};
static const size_t attr_flags_values_max = array_size(attr_flags_values) - 1;

Expand Down Expand Up @@ -2274,6 +2277,52 @@ bgp_attr_encap(
return 0;
}

/* Label index attribute */
static bgp_attr_parse_ret_t
bgp_attr_label_index (struct bgp_attr_parser_args *args, struct bgp_nlri *mp_update)
{
struct peer *const peer = args->peer;
struct attr *const attr = args->attr;
const bgp_size_t length = args->length;
u_int32_t label_index;

/* Length check. */
if (length != 8)
{
zlog_err ("Bad label index length %d", length);

return bgp_attr_malformed (args,
BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
args->total);
}

/* First u32 is currently unused - reserved and flags (undefined) */
stream_getl (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;

attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_LABEL_INDEX);

/*
* Ignore the Label index attribute unless received for labeled-unicast
* SAFI. We reset the flag, though it is probably unnecesary.
*/
if (!mp_update->length || mp_update->afi != SAFI_LABELED_UNICAST)
{
attr->extra->label_index = BGP_INVALID_LABEL_INDEX;
attr->flag &= ~ATTR_FLAG_BIT(BGP_ATTR_LABEL_INDEX);
}
return BGP_ATTR_PARSE_PROCEED;
}

/* BGP unknown attribute treatment. */
static bgp_attr_parse_ret_t
bgp_attr_unknown (struct bgp_attr_parser_args *args)
Expand Down Expand Up @@ -2572,6 +2621,9 @@ bgp_attr_parse (struct peer *peer, struct attr *attr, bgp_size_t size,
case BGP_ATTR_ENCAP:
ret = bgp_attr_encap (type, peer, length, attr, flag, startp);
break;
case BGP_ATTR_LABEL_INDEX:
ret = bgp_attr_label_index (&attr_args, mp_update);
break;
default:
ret = bgp_attr_unknown (&attr_args);
break;
Expand Down Expand Up @@ -2740,6 +2792,10 @@ bgp_packet_mpattr_start (struct stream *s, afi_t afi, safi_t safi, afi_t nh_afi,

if (nh_afi == AFI_MAX)
nh_afi = BGP_NEXTHOP_AFI_FROM_NHLEN(attr->extra->mp_nexthop_len);

if (safi == SAFI_LABELED_UNICAST)
nh_afi = AFI_IP;

/* Nexthop */
switch (nh_afi)
{
Expand All @@ -2748,6 +2804,7 @@ bgp_packet_mpattr_start (struct stream *s, afi_t afi, safi_t safi, afi_t 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);
Expand All @@ -2772,6 +2829,7 @@ bgp_packet_mpattr_start (struct stream *s, afi_t afi, safi_t safi, afi_t nh_afi,
{
case SAFI_UNICAST:
case SAFI_MULTICAST:
case SAFI_LABELED_UNICAST:
{
struct attr_extra *attre = attr->extra;

Expand Down Expand Up @@ -2875,6 +2933,11 @@ bgp_packet_mpattr_prefix (struct stream *s, afi_t afi, safi_t safi,
{
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);
}
Expand Down Expand Up @@ -3112,7 +3175,7 @@ bgp_packet_attribute (struct bgp *bgp, struct peer *peer,
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))
{
/*
* Likely this is the case when an IPv4 prefix was received with
Expand Down Expand Up @@ -3348,6 +3411,23 @@ bgp_packet_attribute (struct bgp *bgp, struct peer *peer,
}
}

/* Label index attribute. */
if (safi == SAFI_LABELED_UNICAST)
{
if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_LABEL_INDEX))
{
u_int32_t label_index;

assert (attr->extra);
label_index = attr->extra->label_index;
stream_putc (s, BGP_ATTR_FLAG_OPTIONAL|BGP_ATTR_FLAG_TRANS);
stream_putc (s, BGP_ATTR_LABEL_INDEX);
stream_putc (s, 8);
stream_putl (s, 0);
stream_putl (s, label_index);
}
}

if ( send_as4_path )
{
/* If the peer is NOT As4 capable, AND */
Expand Down Expand Up @@ -3439,6 +3519,11 @@ bgp_packet_mpunreach_prefix (struct stream *s, struct prefix *p,
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);
}
Expand Down Expand Up @@ -3626,6 +3711,17 @@ bgp_dump_routes_attr (struct stream *s, struct attr *attr,
stream_putc_at (s, sizep, (stream_get_endp (s) - sizep) - 1);
}

/* Label index */
if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_LABEL_INDEX))
{
assert (attr->extra);
stream_putc (s, BGP_ATTR_FLAG_OPTIONAL|BGP_ATTR_FLAG_TRANS);
stream_putc (s, BGP_ATTR_LABEL_INDEX);
stream_putc (s, 8);
stream_putl (s, 0);
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);
Expand Down
7 changes: 5 additions & 2 deletions bgpd/bgp_attr.h
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,9 @@ struct attr_extra
/* route tag */
route_tag_t tag;

/* Label index */
u_int32_t label_index;

uint16_t encap_tunneltype; /* grr */
struct bgp_attr_encap_subtlv *encap_subtlvs; /* rfc5512 */

Expand All @@ -160,7 +163,7 @@ struct attr
unsigned long refcnt;

/* Flag of attribute is set or not. */
u_int32_t flag;
u_int64_t flag;

/* Apart from in6_addr, the remaining static attributes */
struct in_addr nexthop;
Expand Down Expand Up @@ -201,7 +204,7 @@ struct transit
u_char *val;
};

#define ATTR_FLAG_BIT(X) (1 << ((X) - 1))
#define ATTR_FLAG_BIT(X) (1ULL << ((X) - 1))

#define BGP_CLUSTER_LIST_LENGTH(attr) \
(((attr)->flag & ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST)) ? \
Expand Down
4 changes: 4 additions & 0 deletions bgpd/bgp_debug.c
Original file line number Diff line number Diff line change
Expand Up @@ -450,6 +450,10 @@ bgp_dump_attr (struct peer *peer, struct attr *attr, char *buf, size_t size)
snprintf (buf + strlen (buf), size - strlen (buf), ", path %s",
aspath_print (attr->aspath));

if (CHECK_FLAG (attr->flag, ATTR_FLAG_BIT (BGP_ATTR_LABEL_INDEX)))
snprintf (buf + strlen (buf), size - strlen (buf), ", label-index %u",
attr->extra->label_index);

if (strlen (buf) > 1)
return 1;
else
Expand Down
2 changes: 2 additions & 0 deletions bgpd/bgp_fsm.c
Original file line number Diff line number Diff line change
Expand Up @@ -1142,9 +1142,11 @@ bgp_stop (struct peer *peer)
/* Reset prefix count */
peer->pcount[AFI_IP][SAFI_UNICAST] = 0;
peer->pcount[AFI_IP][SAFI_MULTICAST] = 0;
peer->pcount[AFI_IP][SAFI_LABELED_UNICAST] = 0;
peer->pcount[AFI_IP][SAFI_MPLS_VPN] = 0;
peer->pcount[AFI_IP6][SAFI_UNICAST] = 0;
peer->pcount[AFI_IP6][SAFI_MULTICAST] = 0;
peer->pcount[AFI_IP6][SAFI_LABELED_UNICAST] = 0;
#endif /* 0 */

if (!CHECK_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE) &&
Expand Down
2 changes: 2 additions & 0 deletions bgpd/bgp_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,8 @@ bgp_exit (int status)
stream_free (bgp_nexthop_buf);
if (bgp_ifindices_buf)
stream_free (bgp_ifindices_buf);
if (bgp_label_buf)
stream_free (bgp_label_buf);

/* reverse bgp_master_init */
if (bm->master)
Expand Down
18 changes: 11 additions & 7 deletions bgpd/bgp_nht.c
Original file line number Diff line number Diff line change
Expand Up @@ -404,8 +404,9 @@ bgp_parse_nexthop_update (int command, vrf_id_t vrf_id)
{
char buf[PREFIX2STR_BUFFER];
prefix2str(&p, buf, sizeof (buf));
zlog_debug("%d: NH update for %s - metric %d (cur %d) #nhops %d (cur %d)",
vrf_id, buf, metric, bnc->metric, nexthop_num, bnc->nexthop_num);
zlog_debug("%d: Rcvd NH update %s - metric %d/%d #nhops %d/%d flags 0x%x",
vrf_id, buf, metric, bnc->metric, nexthop_num, bnc->nexthop_num,
bnc->flags);
}

if (metric != bnc->metric)
Expand Down Expand Up @@ -678,6 +679,8 @@ evaluate_paths (struct bgp_nexthop_cache *bnc)
struct bgp *bgp = bnc->bgp;
int afi;
struct peer *peer = (struct peer *)bnc->nht_info;
struct bgp_table *table;
safi_t safi;

if (BGP_DEBUG(nht, NHT))
{
Expand All @@ -695,7 +698,10 @@ evaluate_paths (struct bgp_nexthop_cache *bnc)
continue;

rn = path->net;
assert (rn && bgp_node_table (rn));
afi = family2afi(rn->p.family);
table = bgp_node_table (rn);
safi = table->safi;

/* Path becomes valid/invalid depending on whether the nexthop
* reachable/unreachable.
Expand All @@ -705,15 +711,13 @@ evaluate_paths (struct bgp_nexthop_cache *bnc)
{
if (CHECK_FLAG (path->flags, BGP_INFO_VALID))
{
bgp_aggregate_decrement (bgp, &rn->p, path,
afi, SAFI_UNICAST);
bgp_aggregate_decrement (bgp, &rn->p, path, afi, safi);
bgp_info_unset_flag (rn, path, BGP_INFO_VALID);
}
else
{
bgp_info_set_flag (rn, path, BGP_INFO_VALID);
bgp_aggregate_increment (bgp, &rn->p, path,
afi, SAFI_UNICAST);
bgp_aggregate_increment (bgp, &rn->p, path, afi, safi);
}
}

Expand All @@ -727,7 +731,7 @@ evaluate_paths (struct bgp_nexthop_cache *bnc)
CHECK_FLAG(bnc->change_flags, BGP_NEXTHOP_CHANGED))
SET_FLAG(path->flags, BGP_INFO_IGP_CHANGED);

bgp_process(bgp, rn, afi, SAFI_UNICAST);
bgp_process(bgp, rn, afi, safi);
}

if (peer && !CHECK_FLAG(bnc->flags, BGP_NEXTHOP_PEER_NOTIFIED))
Expand Down
8 changes: 8 additions & 0 deletions bgpd/bgp_open.c
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,9 @@ 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_LABELED_UNICAST:
json_object_string_add(json_cap, "capabilityErrorMultiProtocolSafi", "labeled-unicast");
break;
case SAFI_MPLS_VPN:
json_object_string_add(json_cap, "capabilityErrorMultiProtocolSafi", "MPLS-labeled VPN");
break;
Expand Down Expand Up @@ -148,6 +151,9 @@ 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_LABELED_UNICAST:
vty_out (vty, "SAFI Labeled-unicast");
break;
case SAFI_MPLS_VPN:
vty_out (vty, "SAFI MPLS-labeled VPN");
break;
Expand Down Expand Up @@ -1143,10 +1149,12 @@ bgp_open_option_parse (struct peer *peer, u_char length, int *mp_capability)
{
if (! peer->afc_nego[AFI_IP][SAFI_UNICAST]
&& ! peer->afc_nego[AFI_IP][SAFI_MULTICAST]
&& ! peer->afc_nego[AFI_IP][SAFI_LABELED_UNICAST]
&& ! peer->afc_nego[AFI_IP][SAFI_MPLS_VPN]
&& ! peer->afc_nego[AFI_IP][SAFI_ENCAP]
&& ! peer->afc_nego[AFI_IP6][SAFI_UNICAST]
&& ! peer->afc_nego[AFI_IP6][SAFI_MULTICAST]
&& ! peer->afc_nego[AFI_IP6][SAFI_LABELED_UNICAST]
&& ! peer->afc_nego[AFI_IP6][SAFI_MPLS_VPN]
&& ! peer->afc_nego[AFI_IP6][SAFI_ENCAP]
&& ! peer->afc_nego[AFI_L2VPN][SAFI_EVPN])
Expand Down
5 changes: 5 additions & 0 deletions bgpd/bgp_packet.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
#include "bgpd/bgp_advertise.h"
#include "bgpd/bgp_vty.h"
#include "bgpd/bgp_updgrp.h"
#include "bgpd/bgp_label.h"

/* Set up BGP packet marker and packet type. */
int
Expand Down Expand Up @@ -1153,8 +1154,10 @@ bgp_open_receive (struct peer *peer, bgp_size_t size)
{
peer->afc_nego[AFI_IP][SAFI_UNICAST] = peer->afc[AFI_IP][SAFI_UNICAST];
peer->afc_nego[AFI_IP][SAFI_MULTICAST] = peer->afc[AFI_IP][SAFI_MULTICAST];
peer->afc_nego[AFI_IP][SAFI_LABELED_UNICAST] = peer->afc[AFI_IP][SAFI_LABELED_UNICAST];
peer->afc_nego[AFI_IP6][SAFI_UNICAST] = peer->afc[AFI_IP6][SAFI_UNICAST];
peer->afc_nego[AFI_IP6][SAFI_MULTICAST] = peer->afc[AFI_IP6][SAFI_MULTICAST];
peer->afc_nego[AFI_IP6][SAFI_LABELED_UNICAST] = peer->afc[AFI_IP6][SAFI_LABELED_UNICAST];
}

/* When collision is detected and this peer is closed. Retrun
Expand Down Expand Up @@ -1342,6 +1345,8 @@ bgp_nlri_parse (struct peer *peer, struct attr *attr, struct bgp_nlri *packet, i
case SAFI_UNICAST:
case SAFI_MULTICAST:
return bgp_nlri_parse_ip (peer, mp_withdraw?NULL:attr, packet);
case SAFI_LABELED_UNICAST:
return bgp_nlri_parse_label (peer, mp_withdraw?NULL:attr, packet);
case SAFI_MPLS_VPN:
return bgp_nlri_parse_vpn (peer, mp_withdraw?NULL:attr, packet);
case SAFI_ENCAP:
Expand Down
Loading