2023-02-08 13:17:09 +01:00
|
|
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
2015-05-20 03:03:47 +02:00
|
|
|
/**
|
|
|
|
* bgp_updgrp_packet.c: BGP update group packet handling routines
|
|
|
|
*
|
|
|
|
* @copyright Copyright (C) 2014 Cumulus Networks, Inc.
|
|
|
|
*
|
|
|
|
* @author Avneesh Sachdev <avneesh@sproute.net>
|
|
|
|
* @author Rajesh Varadarajan <rajesh@sproute.net>
|
|
|
|
* @author Pradosh Mohapatra <pradosh@sproute.net>
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <zebra.h>
|
|
|
|
|
|
|
|
#include "prefix.h"
|
2023-03-07 20:22:48 +01:00
|
|
|
#include "frrevent.h"
|
2015-05-20 03:03:47 +02:00
|
|
|
#include "buffer.h"
|
|
|
|
#include "stream.h"
|
|
|
|
#include "command.h"
|
|
|
|
#include "sockunion.h"
|
|
|
|
#include "network.h"
|
|
|
|
#include "memory.h"
|
|
|
|
#include "filter.h"
|
|
|
|
#include "routemap.h"
|
|
|
|
#include "log.h"
|
|
|
|
#include "plist.h"
|
|
|
|
#include "linklist.h"
|
|
|
|
#include "workqueue.h"
|
|
|
|
#include "hash.h"
|
|
|
|
#include "queue.h"
|
2017-03-09 15:54:20 +01:00
|
|
|
#include "mpls.h"
|
2015-05-20 03:03:47 +02:00
|
|
|
|
|
|
|
#include "bgpd/bgpd.h"
|
|
|
|
#include "bgpd/bgp_debug.h"
|
2018-06-15 23:08:53 +02:00
|
|
|
#include "bgpd/bgp_errors.h"
|
2015-05-20 03:03:47 +02:00
|
|
|
#include "bgpd/bgp_fsm.h"
|
|
|
|
#include "bgpd/bgp_route.h"
|
|
|
|
#include "bgpd/bgp_packet.h"
|
|
|
|
#include "bgpd/bgp_advertise.h"
|
|
|
|
#include "bgpd/bgp_updgrp.h"
|
|
|
|
#include "bgpd/bgp_nexthop.h"
|
|
|
|
#include "bgpd/bgp_nht.h"
|
2016-08-10 01:02:03 +02:00
|
|
|
#include "bgpd/bgp_mplsvpn.h"
|
2017-03-09 15:54:20 +01:00
|
|
|
#include "bgpd/bgp_label.h"
|
bgpd: Re-use TX Addpath IDs where possible
The motivation for this patch is to address a concerning behavior of
tx-addpath-bestpath-per-AS. Prior to this patch, all paths' TX ID was
pre-determined as the path was received from a peer. However, this meant
that any time the path selected as best from an AS changed, bgpd had no
choice but to withdraw the previous best path, and advertise the new
best-path under a new TX ID. This could cause significant network
disruption, especially for the subset of prefixes coming from only one
AS that were also communicated over a bestpath-per-AS session.
The patch's general approach is best illustrated by
txaddpath_update_ids. After a bestpath run (required for best-per-AS to
know what will and will not be sent as addpaths) ID numbers will be
stripped from paths that no longer need to be sent, and held in a pool.
Then, paths that will be sent as addpaths and do not already have ID
numbers will allocate new ID numbers, pulling first from that pool.
Finally, anything left in the pool will be returned to the allocator.
In order for this to work, ID numbers had to be split by strategy. The
tx-addpath-All strategy would keep every ID number "in use" constantly,
preventing IDs from being transferred to different paths. Rather than
create two variables for ID, this patch create a more generic array that
will easily enable more addpath strategies to be implemented. The
previously described ID manipulations will happen per addpath strategy,
and will only be run for strategies that are enabled on at least one
peer.
Finally, the ID numbers are allocated from an allocator that tracks per
AFI/SAFI/Addpath Strategy which IDs are in use. Though it would be very
improbable, there was the possibility with the free-running counter
approach for rollover to cause two paths on the same prefix to get
assigned the same TX ID. As remote as the possibility is, we prefer to
not leave it to chance.
This ID re-use method is not perfect. In some cases you could still get
withdraw-then-add behaviors where not strictly necessary. In the case of
bestpath-per-AS this requires one AS to advertise a prefix for the first
time, then a second AS withdraws that prefix, all within the space of an
already pending MRAI timer. In those situations a withdraw-then-add is
more forgivable, and fixing it would probably require a much more
significant effort, as IDs would need to be moved to ADVs instead of
paths.
Signed-off-by Mitchell Skiba <mskiba@amazon.com>
2018-05-10 01:10:02 +02:00
|
|
|
#include "bgpd/bgp_addpath.h"
|
2015-05-20 03:03:47 +02:00
|
|
|
|
|
|
|
/********************
|
|
|
|
* PRIVATE FUNCTIONS
|
|
|
|
********************/
|
|
|
|
|
|
|
|
/********************
|
|
|
|
* PUBLIC FUNCTIONS
|
|
|
|
********************/
|
2019-01-24 10:12:36 +01:00
|
|
|
struct bpacket *bpacket_alloc(void)
|
2015-05-20 03:03:47 +02:00
|
|
|
{
|
|
|
|
struct bpacket *pkt;
|
|
|
|
|
2019-02-25 21:30:31 +01:00
|
|
|
pkt = XCALLOC(MTYPE_BGP_PACKET, sizeof(struct bpacket));
|
2015-05-20 03:03:47 +02:00
|
|
|
|
|
|
|
return pkt;
|
|
|
|
}
|
|
|
|
|
|
|
|
void bpacket_free(struct bpacket *pkt)
|
|
|
|
{
|
|
|
|
if (pkt->buffer)
|
|
|
|
stream_free(pkt->buffer);
|
|
|
|
pkt->buffer = NULL;
|
|
|
|
XFREE(MTYPE_BGP_PACKET, pkt);
|
|
|
|
}
|
|
|
|
|
|
|
|
void bpacket_queue_init(struct bpacket_queue *q)
|
|
|
|
{
|
|
|
|
TAILQ_INIT(&(q->pkts));
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* bpacket_queue_add_packet
|
|
|
|
*
|
|
|
|
* Internal function of bpacket_queue - and adds a
|
|
|
|
* packet entry to the end of the list.
|
|
|
|
*
|
|
|
|
* Users of bpacket_queue should use bpacket_queue_add instead.
|
|
|
|
*/
|
|
|
|
static void bpacket_queue_add_packet(struct bpacket_queue *q,
|
|
|
|
struct bpacket *pkt)
|
|
|
|
{
|
|
|
|
struct bpacket *last_pkt;
|
|
|
|
|
|
|
|
if (TAILQ_EMPTY(&(q->pkts)))
|
|
|
|
TAILQ_INSERT_TAIL(&(q->pkts), pkt, pkt_train);
|
|
|
|
else {
|
|
|
|
last_pkt = bpacket_queue_last(q);
|
|
|
|
TAILQ_INSERT_AFTER(&(q->pkts), last_pkt, pkt, pkt_train);
|
|
|
|
}
|
|
|
|
q->curr_count++;
|
|
|
|
if (q->hwm_count < q->curr_count)
|
|
|
|
q->hwm_count = q->curr_count;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Adds a packet to the bpacket_queue.
|
|
|
|
*
|
|
|
|
* The stream passed is consumed by this function. So, the caller should
|
|
|
|
* not free or use the stream after
|
|
|
|
* invoking this function.
|
|
|
|
*/
|
|
|
|
struct bpacket *bpacket_queue_add(struct bpacket_queue *q, struct stream *s,
|
|
|
|
struct bpacket_attr_vec_arr *vecarrp)
|
|
|
|
{
|
|
|
|
struct bpacket *pkt;
|
|
|
|
struct bpacket *last_pkt;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
|
|
|
|
2015-05-20 03:03:47 +02:00
|
|
|
pkt = bpacket_alloc();
|
|
|
|
if (TAILQ_EMPTY(&(q->pkts))) {
|
|
|
|
pkt->ver = 1;
|
|
|
|
pkt->buffer = s;
|
|
|
|
if (vecarrp)
|
|
|
|
memcpy(&pkt->arr, vecarrp,
|
|
|
|
sizeof(struct bpacket_attr_vec_arr));
|
|
|
|
else
|
|
|
|
bpacket_attr_vec_arr_reset(&pkt->arr);
|
|
|
|
bpacket_queue_add_packet(q, pkt);
|
|
|
|
return pkt;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Fill in the new information into the current sentinel and create a
|
|
|
|
* new sentinel.
|
|
|
|
*/
|
|
|
|
last_pkt = bpacket_queue_last(q);
|
|
|
|
assert(last_pkt->buffer == NULL);
|
|
|
|
last_pkt->buffer = s;
|
|
|
|
if (vecarrp)
|
|
|
|
memcpy(&last_pkt->arr, vecarrp,
|
|
|
|
sizeof(struct bpacket_attr_vec_arr));
|
|
|
|
else
|
|
|
|
bpacket_attr_vec_arr_reset(&last_pkt->arr);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2015-05-20 03:03:47 +02:00
|
|
|
pkt->ver = last_pkt->ver;
|
|
|
|
pkt->ver++;
|
|
|
|
bpacket_queue_add_packet(q, pkt);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2015-05-20 03:03:47 +02:00
|
|
|
return last_pkt;
|
|
|
|
}
|
|
|
|
|
|
|
|
struct bpacket *bpacket_queue_first(struct bpacket_queue *q)
|
|
|
|
{
|
|
|
|
return (TAILQ_FIRST(&(q->pkts)));
|
|
|
|
}
|
|
|
|
|
|
|
|
struct bpacket *bpacket_queue_last(struct bpacket_queue *q)
|
|
|
|
{
|
|
|
|
return TAILQ_LAST(&(q->pkts), pkt_queue);
|
|
|
|
}
|
|
|
|
|
|
|
|
struct bpacket *bpacket_queue_remove(struct bpacket_queue *q)
|
|
|
|
{
|
|
|
|
struct bpacket *first;
|
|
|
|
|
|
|
|
first = bpacket_queue_first(q);
|
|
|
|
if (first) {
|
|
|
|
TAILQ_REMOVE(&(q->pkts), first, pkt_train);
|
|
|
|
q->curr_count--;
|
|
|
|
}
|
|
|
|
return first;
|
|
|
|
}
|
|
|
|
|
|
|
|
unsigned int bpacket_queue_length(struct bpacket_queue *q)
|
|
|
|
{
|
|
|
|
return q->curr_count - 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
unsigned int bpacket_queue_hwm_length(struct bpacket_queue *q)
|
|
|
|
{
|
|
|
|
return q->hwm_count - 1;
|
|
|
|
}
|
|
|
|
|
2020-03-20 10:57:54 +01:00
|
|
|
bool bpacket_queue_is_full(struct bgp *bgp, struct bpacket_queue *q)
|
2015-05-20 03:03:47 +02:00
|
|
|
{
|
|
|
|
if (q->curr_count >= bgp->default_subgroup_pkt_queue_max)
|
2020-03-20 10:57:54 +01:00
|
|
|
return true;
|
|
|
|
return false;
|
2015-05-20 03:03:47 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void bpacket_add_peer(struct bpacket *pkt, struct peer_af *paf)
|
|
|
|
{
|
|
|
|
if (!pkt || !paf)
|
|
|
|
return;
|
|
|
|
|
|
|
|
LIST_INSERT_HEAD(&(pkt->peers), paf, pkt_train);
|
|
|
|
paf->next_pkt_to_send = pkt;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* bpacket_queue_cleanup
|
|
|
|
*/
|
|
|
|
void bpacket_queue_cleanup(struct bpacket_queue *q)
|
|
|
|
{
|
|
|
|
struct bpacket *pkt;
|
|
|
|
|
|
|
|
while ((pkt = bpacket_queue_remove(q))) {
|
|
|
|
bpacket_free(pkt);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* bpacket_queue_compact
|
|
|
|
*
|
|
|
|
* Delete packets that do not need to be transmitted to any peer from
|
|
|
|
* the queue.
|
|
|
|
*
|
|
|
|
* @return the number of packets deleted.
|
|
|
|
*/
|
|
|
|
static int bpacket_queue_compact(struct bpacket_queue *q)
|
|
|
|
{
|
|
|
|
int num_deleted;
|
|
|
|
struct bpacket *pkt, *removed_pkt;
|
|
|
|
|
|
|
|
num_deleted = 0;
|
|
|
|
|
|
|
|
while (1) {
|
|
|
|
pkt = bpacket_queue_first(q);
|
|
|
|
if (!pkt)
|
|
|
|
break;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Don't delete the sentinel.
|
|
|
|
*/
|
|
|
|
if (!pkt->buffer)
|
|
|
|
break;
|
|
|
|
|
|
|
|
if (!LIST_EMPTY(&(pkt->peers)))
|
|
|
|
break;
|
|
|
|
|
|
|
|
removed_pkt = bpacket_queue_remove(q);
|
|
|
|
assert(pkt == removed_pkt);
|
|
|
|
bpacket_free(removed_pkt);
|
|
|
|
|
|
|
|
num_deleted++;
|
|
|
|
}
|
|
|
|
|
|
|
|
return num_deleted;
|
|
|
|
}
|
|
|
|
|
|
|
|
void bpacket_queue_advance_peer(struct peer_af *paf)
|
|
|
|
{
|
|
|
|
struct bpacket *pkt;
|
|
|
|
struct bpacket *old_pkt;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2015-05-20 03:03:47 +02:00
|
|
|
old_pkt = paf->next_pkt_to_send;
|
|
|
|
if (old_pkt->buffer == NULL)
|
|
|
|
/* Already at end of list */
|
|
|
|
return;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2015-05-20 03:03:47 +02:00
|
|
|
LIST_REMOVE(paf, pkt_train);
|
|
|
|
pkt = TAILQ_NEXT(old_pkt, pkt_train);
|
|
|
|
bpacket_add_peer(pkt, paf);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2015-05-20 03:03:47 +02:00
|
|
|
if (!bpacket_queue_compact(PAF_PKTQ(paf)))
|
|
|
|
return;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2015-05-20 03:03:47 +02:00
|
|
|
/*
|
|
|
|
* Deleted one or more packets. Check if we can now merge this
|
|
|
|
* peer's subgroup into another subgroup.
|
|
|
|
*/
|
|
|
|
update_subgroup_check_merge(paf->subgroup, "advanced peer in queue");
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* bpacket_queue_remove_peer
|
|
|
|
*
|
|
|
|
* Remove the peer from the packet queue of the subgroup it belongs
|
|
|
|
* to.
|
|
|
|
*/
|
|
|
|
void bpacket_queue_remove_peer(struct peer_af *paf)
|
|
|
|
{
|
|
|
|
struct bpacket_queue *q;
|
|
|
|
|
|
|
|
q = PAF_PKTQ(paf);
|
|
|
|
assert(q);
|
|
|
|
|
|
|
|
LIST_REMOVE(paf, pkt_train);
|
|
|
|
paf->next_pkt_to_send = NULL;
|
|
|
|
|
|
|
|
bpacket_queue_compact(q);
|
|
|
|
}
|
|
|
|
|
|
|
|
unsigned int bpacket_queue_virtual_length(struct peer_af *paf)
|
|
|
|
{
|
|
|
|
struct bpacket *pkt;
|
|
|
|
struct bpacket *last;
|
|
|
|
struct bpacket_queue *q;
|
|
|
|
|
|
|
|
pkt = paf->next_pkt_to_send;
|
|
|
|
if (!pkt || (pkt->buffer == NULL))
|
|
|
|
/* Already at end of list */
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
q = PAF_PKTQ(paf);
|
|
|
|
if (TAILQ_EMPTY(&(q->pkts)))
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
last = TAILQ_LAST(&(q->pkts), pkt_queue);
|
|
|
|
if (last->ver >= pkt->ver)
|
|
|
|
return last->ver - pkt->ver;
|
|
|
|
|
|
|
|
/* sequence # rolled over */
|
|
|
|
return (UINT_MAX - pkt->ver + 1) + last->ver;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Dump the bpacket queue
|
|
|
|
*/
|
|
|
|
void bpacket_queue_show_vty(struct bpacket_queue *q, struct vty *vty)
|
|
|
|
{
|
|
|
|
struct bpacket *pkt;
|
|
|
|
struct peer_af *paf;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2015-05-20 03:03:47 +02:00
|
|
|
pkt = bpacket_queue_first(q);
|
|
|
|
while (pkt) {
|
2017-07-13 17:49:13 +02:00
|
|
|
vty_out(vty, " Packet %p ver %u buffer %p\n", pkt, pkt->ver,
|
2017-06-21 05:10:57 +02:00
|
|
|
pkt->buffer);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2017-09-15 17:47:35 +02:00
|
|
|
LIST_FOREACH (paf, &(pkt->peers), pkt_train) {
|
2017-07-13 17:49:13 +02:00
|
|
|
vty_out(vty, " - %s\n", paf->peer->host);
|
2015-05-20 03:03:47 +02:00
|
|
|
}
|
|
|
|
pkt = bpacket_next(pkt);
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
struct stream *bpacket_reformat_for_peer(struct bpacket *pkt,
|
|
|
|
struct peer_af *paf)
|
|
|
|
{
|
|
|
|
struct stream *s = NULL;
|
|
|
|
bpacket_attr_vec *vec;
|
2015-06-12 16:58:14 +02:00
|
|
|
struct peer *peer;
|
2019-09-24 14:02:02 +02:00
|
|
|
struct bgp_filter *filter;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2015-05-20 03:03:47 +02:00
|
|
|
s = stream_dup(pkt->buffer);
|
2015-06-12 16:58:14 +02:00
|
|
|
peer = PAF_PEER(paf);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2015-05-20 03:03:47 +02:00
|
|
|
vec = &pkt->arr.entries[BGP_ATTR_VEC_NH];
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2020-02-11 04:03:02 +01:00
|
|
|
if (!CHECK_FLAG(vec->flags, BPKT_ATTRVEC_FLAGS_UPDATED))
|
|
|
|
return s;
|
|
|
|
|
|
|
|
uint8_t nhlen;
|
|
|
|
afi_t nhafi;
|
|
|
|
int route_map_sets_nh;
|
|
|
|
|
|
|
|
nhlen = stream_getc_from(s, vec->offset);
|
|
|
|
filter = &peer->filter[paf->afi][paf->safi];
|
|
|
|
|
|
|
|
if (peer_cap_enhe(peer, paf->afi, paf->safi))
|
|
|
|
nhafi = AFI_IP6;
|
|
|
|
else
|
|
|
|
nhafi = BGP_NEXTHOP_AFI_FROM_NHLEN(nhlen);
|
|
|
|
|
|
|
|
if (nhafi == AFI_IP) {
|
|
|
|
struct in_addr v4nh, *mod_v4nh;
|
|
|
|
int nh_modified = 0;
|
|
|
|
size_t offset_nh = vec->offset + 1;
|
|
|
|
|
|
|
|
route_map_sets_nh =
|
|
|
|
(CHECK_FLAG(vec->flags,
|
bgpd: Allow overriding MPLS VPN next-hops via route-maps
Just do not reset next-hop for MPLS VPN routes.
Example of 172.16.255.1/32 (using extended next-hop capability):
```
pe2# sh bgp ipv4 vpn
BGP table version is 4, local router ID is 10.10.10.20, vrf id 0
Default local pref 100, local AS 65001
Status codes: s suppressed, d damped, h history, * valid, > best, = multipath,
i internal, r RIB-failure, S Stale, R Removed
Nexthop codes: @NNN nexthop's vrf id, < announce-nh-self
Origin codes: i - IGP, e - EGP, ? - incomplete
RPKI validation codes: V valid, I invalid, N Not found
Network Next Hop Metric LocPrf Weight Path
Route Distinguisher: 192.168.1.2:2
*>i10.0.0.0/24 2001:db8:1::1 0 100 0 65000 ?
UN=2001:db8:1::1 EC{192.168.1.2:2} label=1111 type=bgp, subtype=0
*>i172.16.255.1/32 2001:db8::1 0 100 0 65000 ?
UN=2001:db8::1 EC{192.168.1.2:2} label=1111 type=bgp, subtype=0
*>i192.168.1.0/24 2001:db8:1::1 0 100 0 65000 ?
UN=2001:db8:1::1 EC{192.168.1.2:2} label=1111 type=bgp, subtype=0
*>i192.168.2.0/24 2001:db8:1::1 100 0 65000 ?
UN=2001:db8:1::1 EC{192.168.1.2:2} label=1111 type=bgp, subtype=0
Route Distinguisher: 192.168.2.2:2
*> 10.0.0.0/24 192.168.2.1@4< 0 50 0 65000 ?
UN=192.168.2.1 EC{192.168.2.2:2} label=2222 type=bgp, subtype=5
*> 172.16.255.1/32 192.168.2.1@4< 50 0 65000 ?
UN=192.168.2.1 EC{192.168.2.2:2} label=2222 type=bgp, subtype=5
*> 192.168.1.0/24 192.168.2.1@4< 50 0 65000 ?
UN=192.168.2.1 EC{192.168.2.2:2} label=2222 type=bgp, subtype=5
*> 192.168.2.0/24 192.168.2.1@4< 0 50 0 65000 ?
UN=192.168.2.1 EC{192.168.2.2:2} label=2222 type=bgp, subtype=5
Displayed 8 routes and 8 total paths
```
Signed-off-by: Donatas Abraitis <donatas@opensourcerouting.org>
2022-11-18 14:47:50 +01:00
|
|
|
BPKT_ATTRVEC_FLAGS_RMAP_IPV4_NH_CHANGED) ||
|
|
|
|
CHECK_FLAG(vec->flags,
|
|
|
|
BPKT_ATTRVEC_FLAGS_RMAP_VPNV4_NH_CHANGED) ||
|
|
|
|
CHECK_FLAG(vec->flags,
|
|
|
|
BPKT_ATTRVEC_FLAGS_RMAP_NH_PEER_ADDRESS));
|
2020-02-11 04:03:02 +01:00
|
|
|
|
|
|
|
switch (nhlen) {
|
|
|
|
case BGP_ATTR_NHLEN_IPV4:
|
|
|
|
break;
|
|
|
|
case BGP_ATTR_NHLEN_VPNV4:
|
|
|
|
offset_nh += 8;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
/* TODO: handle IPv6 nexthops */
|
|
|
|
flog_warn(
|
|
|
|
EC_BGP_INVALID_NEXTHOP_LENGTH,
|
|
|
|
"%s: %s: invalid MP nexthop length (AFI IP): %u",
|
|
|
|
__func__, peer->host, nhlen);
|
|
|
|
stream_free(s);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
stream_get_from(&v4nh, s, offset_nh, IPV4_MAX_BYTELEN);
|
|
|
|
mod_v4nh = &v4nh;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* If route-map has set the nexthop, that is normally
|
|
|
|
* used; if it is specified as peer-address, the peering
|
|
|
|
* address is picked up. Otherwise, if NH is unavailable
|
|
|
|
* from attribute, the peering addr is picked up; the
|
|
|
|
* "NH unavailable" case also covers next-hop-self and
|
|
|
|
* some other scenarios - see subgroup_announce_check().
|
|
|
|
* In all other cases, use the nexthop carried in the
|
|
|
|
* attribute unless it is EBGP non-multiaccess and there
|
|
|
|
* is no next-hop-unchanged setting or the peer is EBGP
|
|
|
|
* and the route-map that changed the next-hop value
|
|
|
|
* was applied inbound rather than outbound. Updates to
|
|
|
|
* an EBGP peer should only modify the next-hop if it
|
|
|
|
* was set in an outbound route-map to that peer.
|
|
|
|
* Note: It is assumed route-map cannot set the nexthop
|
|
|
|
* to an invalid value.
|
|
|
|
*/
|
|
|
|
if (route_map_sets_nh
|
|
|
|
&& ((peer->sort != BGP_PEER_EBGP)
|
|
|
|
|| ROUTE_MAP_OUT(filter))) {
|
|
|
|
if (CHECK_FLAG(
|
|
|
|
vec->flags,
|
|
|
|
BPKT_ATTRVEC_FLAGS_RMAP_NH_PEER_ADDRESS)) {
|
2017-05-19 15:51:00 +02:00
|
|
|
mod_v4nh = &peer->nexthop.v4;
|
|
|
|
nh_modified = 1;
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
2020-02-11 04:03:02 +01:00
|
|
|
} else if (v4nh.s_addr == INADDR_ANY) {
|
|
|
|
mod_v4nh = &peer->nexthop.v4;
|
|
|
|
nh_modified = 1;
|
|
|
|
} else if (peer->sort == BGP_PEER_EBGP
|
|
|
|
&& (bgp_multiaccess_check_v4(v4nh, peer) == 0)
|
|
|
|
&& !CHECK_FLAG(vec->flags,
|
|
|
|
BPKT_ATTRVEC_FLAGS_RMAP_NH_UNCHANGED)
|
|
|
|
&& !peer_af_flag_check(
|
|
|
|
peer, paf->afi, paf->safi,
|
|
|
|
PEER_FLAG_NEXTHOP_UNCHANGED)) {
|
|
|
|
/* NOTE: not handling case where NH has new AFI
|
|
|
|
*/
|
|
|
|
mod_v4nh = &peer->nexthop.v4;
|
|
|
|
nh_modified = 1;
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2020-02-11 04:03:02 +01:00
|
|
|
if (nh_modified) /* allow for VPN RD */
|
|
|
|
stream_put_in_addr_at(s, offset_nh, mod_v4nh);
|
|
|
|
|
|
|
|
if (bgp_debug_update(peer, NULL, NULL, 0))
|
2020-10-15 21:33:09 +02:00
|
|
|
zlog_debug("u%" PRIu64 ":s%" PRIu64
|
|
|
|
" %s send UPDATE w/ nexthop %pI4%s",
|
2020-02-11 04:03:02 +01:00
|
|
|
PAF_SUBGRP(paf)->update_group->id,
|
2020-10-15 21:33:09 +02:00
|
|
|
PAF_SUBGRP(paf)->id, peer->host, mod_v4nh,
|
2020-06-13 19:36:59 +02:00
|
|
|
(nhlen == BGP_ATTR_NHLEN_VPNV4 ? " and RD"
|
|
|
|
: ""));
|
2020-02-11 04:03:02 +01:00
|
|
|
} else if (nhafi == AFI_IP6) {
|
|
|
|
struct in6_addr v6nhglobal, *mod_v6nhg;
|
|
|
|
struct in6_addr v6nhlocal, *mod_v6nhl;
|
|
|
|
int gnh_modified, lnh_modified;
|
|
|
|
size_t offset_nhglobal = vec->offset + 1;
|
|
|
|
size_t offset_nhlocal = vec->offset + 1;
|
|
|
|
|
|
|
|
gnh_modified = lnh_modified = 0;
|
|
|
|
mod_v6nhg = &v6nhglobal;
|
|
|
|
mod_v6nhl = &v6nhlocal;
|
|
|
|
|
|
|
|
route_map_sets_nh =
|
|
|
|
(CHECK_FLAG(vec->flags,
|
bgpd: Allow overriding MPLS VPN next-hops via route-maps
Just do not reset next-hop for MPLS VPN routes.
Example of 172.16.255.1/32 (using extended next-hop capability):
```
pe2# sh bgp ipv4 vpn
BGP table version is 4, local router ID is 10.10.10.20, vrf id 0
Default local pref 100, local AS 65001
Status codes: s suppressed, d damped, h history, * valid, > best, = multipath,
i internal, r RIB-failure, S Stale, R Removed
Nexthop codes: @NNN nexthop's vrf id, < announce-nh-self
Origin codes: i - IGP, e - EGP, ? - incomplete
RPKI validation codes: V valid, I invalid, N Not found
Network Next Hop Metric LocPrf Weight Path
Route Distinguisher: 192.168.1.2:2
*>i10.0.0.0/24 2001:db8:1::1 0 100 0 65000 ?
UN=2001:db8:1::1 EC{192.168.1.2:2} label=1111 type=bgp, subtype=0
*>i172.16.255.1/32 2001:db8::1 0 100 0 65000 ?
UN=2001:db8::1 EC{192.168.1.2:2} label=1111 type=bgp, subtype=0
*>i192.168.1.0/24 2001:db8:1::1 0 100 0 65000 ?
UN=2001:db8:1::1 EC{192.168.1.2:2} label=1111 type=bgp, subtype=0
*>i192.168.2.0/24 2001:db8:1::1 100 0 65000 ?
UN=2001:db8:1::1 EC{192.168.1.2:2} label=1111 type=bgp, subtype=0
Route Distinguisher: 192.168.2.2:2
*> 10.0.0.0/24 192.168.2.1@4< 0 50 0 65000 ?
UN=192.168.2.1 EC{192.168.2.2:2} label=2222 type=bgp, subtype=5
*> 172.16.255.1/32 192.168.2.1@4< 50 0 65000 ?
UN=192.168.2.1 EC{192.168.2.2:2} label=2222 type=bgp, subtype=5
*> 192.168.1.0/24 192.168.2.1@4< 50 0 65000 ?
UN=192.168.2.1 EC{192.168.2.2:2} label=2222 type=bgp, subtype=5
*> 192.168.2.0/24 192.168.2.1@4< 0 50 0 65000 ?
UN=192.168.2.1 EC{192.168.2.2:2} label=2222 type=bgp, subtype=5
Displayed 8 routes and 8 total paths
```
Signed-off-by: Donatas Abraitis <donatas@opensourcerouting.org>
2022-11-18 14:47:50 +01:00
|
|
|
BPKT_ATTRVEC_FLAGS_RMAP_IPV6_GNH_CHANGED) ||
|
|
|
|
CHECK_FLAG(
|
2020-02-11 04:03:02 +01:00
|
|
|
vec->flags,
|
bgpd: Allow overriding MPLS VPN next-hops via route-maps
Just do not reset next-hop for MPLS VPN routes.
Example of 172.16.255.1/32 (using extended next-hop capability):
```
pe2# sh bgp ipv4 vpn
BGP table version is 4, local router ID is 10.10.10.20, vrf id 0
Default local pref 100, local AS 65001
Status codes: s suppressed, d damped, h history, * valid, > best, = multipath,
i internal, r RIB-failure, S Stale, R Removed
Nexthop codes: @NNN nexthop's vrf id, < announce-nh-self
Origin codes: i - IGP, e - EGP, ? - incomplete
RPKI validation codes: V valid, I invalid, N Not found
Network Next Hop Metric LocPrf Weight Path
Route Distinguisher: 192.168.1.2:2
*>i10.0.0.0/24 2001:db8:1::1 0 100 0 65000 ?
UN=2001:db8:1::1 EC{192.168.1.2:2} label=1111 type=bgp, subtype=0
*>i172.16.255.1/32 2001:db8::1 0 100 0 65000 ?
UN=2001:db8::1 EC{192.168.1.2:2} label=1111 type=bgp, subtype=0
*>i192.168.1.0/24 2001:db8:1::1 0 100 0 65000 ?
UN=2001:db8:1::1 EC{192.168.1.2:2} label=1111 type=bgp, subtype=0
*>i192.168.2.0/24 2001:db8:1::1 100 0 65000 ?
UN=2001:db8:1::1 EC{192.168.1.2:2} label=1111 type=bgp, subtype=0
Route Distinguisher: 192.168.2.2:2
*> 10.0.0.0/24 192.168.2.1@4< 0 50 0 65000 ?
UN=192.168.2.1 EC{192.168.2.2:2} label=2222 type=bgp, subtype=5
*> 172.16.255.1/32 192.168.2.1@4< 50 0 65000 ?
UN=192.168.2.1 EC{192.168.2.2:2} label=2222 type=bgp, subtype=5
*> 192.168.1.0/24 192.168.2.1@4< 50 0 65000 ?
UN=192.168.2.1 EC{192.168.2.2:2} label=2222 type=bgp, subtype=5
*> 192.168.2.0/24 192.168.2.1@4< 0 50 0 65000 ?
UN=192.168.2.1 EC{192.168.2.2:2} label=2222 type=bgp, subtype=5
Displayed 8 routes and 8 total paths
```
Signed-off-by: Donatas Abraitis <donatas@opensourcerouting.org>
2022-11-18 14:47:50 +01:00
|
|
|
BPKT_ATTRVEC_FLAGS_RMAP_VPNV6_GNH_CHANGED) ||
|
|
|
|
CHECK_FLAG(vec->flags,
|
|
|
|
BPKT_ATTRVEC_FLAGS_RMAP_NH_PEER_ADDRESS));
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2020-02-11 04:03:02 +01:00
|
|
|
/*
|
|
|
|
* The logic here is rather similar to that for IPv4, the
|
|
|
|
* additional work being to handle 1 or 2 nexthops.
|
|
|
|
* Also, 3rd party nexthop is not propagated for EBGP
|
|
|
|
* right now.
|
|
|
|
*/
|
|
|
|
switch (nhlen) {
|
|
|
|
case BGP_ATTR_NHLEN_IPV6_GLOBAL:
|
|
|
|
break;
|
|
|
|
case BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL:
|
|
|
|
offset_nhlocal += IPV6_MAX_BYTELEN;
|
|
|
|
break;
|
|
|
|
case BGP_ATTR_NHLEN_VPNV6_GLOBAL:
|
|
|
|
offset_nhglobal += 8;
|
|
|
|
break;
|
|
|
|
case BGP_ATTR_NHLEN_VPNV6_GLOBAL_AND_LL:
|
|
|
|
offset_nhglobal += 8;
|
|
|
|
offset_nhlocal += 8 * 2 + IPV6_MAX_BYTELEN;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
/* TODO: handle IPv4 nexthops */
|
|
|
|
flog_warn(
|
|
|
|
EC_BGP_INVALID_NEXTHOP_LENGTH,
|
|
|
|
"%s: %s: invalid MP nexthop length (AFI IP6): %u",
|
|
|
|
__func__, peer->host, nhlen);
|
|
|
|
stream_free(s);
|
|
|
|
return NULL;
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2020-02-11 04:03:02 +01:00
|
|
|
stream_get_from(&v6nhglobal, s, offset_nhglobal,
|
|
|
|
IPV6_MAX_BYTELEN);
|
2019-09-24 14:02:02 +02:00
|
|
|
|
2020-02-11 04:03:02 +01:00
|
|
|
/*
|
|
|
|
* Updates to an EBGP peer should only modify the
|
|
|
|
* next-hop if it was set in an outbound route-map
|
|
|
|
* to that peer.
|
|
|
|
*/
|
|
|
|
if (route_map_sets_nh
|
|
|
|
&& ((peer->sort != BGP_PEER_EBGP)
|
|
|
|
|| ROUTE_MAP_OUT(filter))) {
|
|
|
|
if (CHECK_FLAG(
|
|
|
|
vec->flags,
|
|
|
|
BPKT_ATTRVEC_FLAGS_RMAP_NH_PEER_ADDRESS)) {
|
2015-06-12 16:58:14 +02:00
|
|
|
mod_v6nhg = &peer->nexthop.v6_global;
|
|
|
|
gnh_modified = 1;
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
2020-02-11 04:03:02 +01:00
|
|
|
} else if (IN6_IS_ADDR_UNSPECIFIED(&v6nhglobal)) {
|
|
|
|
mod_v6nhg = &peer->nexthop.v6_global;
|
|
|
|
gnh_modified = 1;
|
|
|
|
} else if ((peer->sort == BGP_PEER_EBGP)
|
|
|
|
&& (!bgp_multiaccess_check_v6(v6nhglobal, peer))
|
|
|
|
&& !CHECK_FLAG(vec->flags,
|
|
|
|
BPKT_ATTRVEC_FLAGS_RMAP_NH_UNCHANGED)
|
|
|
|
&& !peer_af_flag_check(
|
2022-10-27 03:17:50 +02:00
|
|
|
peer, paf->afi, paf->safi,
|
2020-02-11 04:03:02 +01:00
|
|
|
PEER_FLAG_NEXTHOP_UNCHANGED)) {
|
|
|
|
/* NOTE: not handling case where NH has new AFI
|
|
|
|
*/
|
|
|
|
mod_v6nhg = &peer->nexthop.v6_global;
|
|
|
|
gnh_modified = 1;
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2024-03-29 16:14:14 +01:00
|
|
|
if (peer->nexthop.v4.s_addr != INADDR_ANY &&
|
|
|
|
(IN6_IS_ADDR_UNSPECIFIED(mod_v6nhg) ||
|
|
|
|
(IN6_IS_ADDR_LINKLOCAL(mod_v6nhg) &&
|
|
|
|
peer->connection->su.sa.sa_family == AF_INET6 &&
|
|
|
|
paf->afi == AFI_IP))) {
|
|
|
|
ipv4_to_ipv4_mapped_ipv6(mod_v6nhg, peer->nexthop.v4);
|
|
|
|
gnh_modified = 1;
|
2020-07-29 17:48:57 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if (IS_MAPPED_IPV6(&peer->nexthop.v6_global)) {
|
|
|
|
mod_v6nhg = &peer->nexthop.v6_global;
|
|
|
|
gnh_modified = 1;
|
|
|
|
}
|
|
|
|
|
2020-02-11 04:03:02 +01:00
|
|
|
if (nhlen == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL
|
|
|
|
|| nhlen == BGP_ATTR_NHLEN_VPNV6_GLOBAL_AND_LL) {
|
|
|
|
stream_get_from(&v6nhlocal, s, offset_nhlocal,
|
|
|
|
IPV6_MAX_BYTELEN);
|
|
|
|
if (IN6_IS_ADDR_UNSPECIFIED(&v6nhlocal)) {
|
|
|
|
mod_v6nhl = &peer->nexthop.v6_local;
|
|
|
|
lnh_modified = 1;
|
2015-05-20 03:03:47 +02:00
|
|
|
}
|
2020-02-11 04:03:02 +01:00
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2020-02-11 04:03:02 +01:00
|
|
|
if (gnh_modified)
|
|
|
|
stream_put_in6_addr_at(s, offset_nhglobal, mod_v6nhg);
|
|
|
|
if (lnh_modified)
|
|
|
|
stream_put_in6_addr_at(s, offset_nhlocal, mod_v6nhl);
|
|
|
|
|
|
|
|
if (bgp_debug_update(peer, NULL, NULL, 0)) {
|
2020-06-13 19:36:59 +02:00
|
|
|
if (nhlen == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL
|
|
|
|
|| nhlen == BGP_ATTR_NHLEN_VPNV6_GLOBAL_AND_LL)
|
2020-02-11 04:03:02 +01:00
|
|
|
zlog_debug(
|
2021-03-10 01:50:42 +01:00
|
|
|
"u%" PRIu64 ":s%" PRIu64
|
|
|
|
" %s send UPDATE w/ mp_nexthops %pI6, %pI6%s",
|
2020-02-11 04:03:02 +01:00
|
|
|
PAF_SUBGRP(paf)->update_group->id,
|
|
|
|
PAF_SUBGRP(paf)->id, peer->host,
|
2021-03-10 01:50:42 +01:00
|
|
|
mod_v6nhg, mod_v6nhl,
|
2020-06-13 19:36:59 +02:00
|
|
|
(nhlen == BGP_ATTR_NHLEN_VPNV6_GLOBAL_AND_LL
|
|
|
|
? " and RD"
|
|
|
|
: ""));
|
2020-02-11 04:03:02 +01:00
|
|
|
else
|
2021-03-10 01:50:42 +01:00
|
|
|
zlog_debug(
|
|
|
|
"u%" PRIu64 ":s%" PRIu64
|
|
|
|
" %s send UPDATE w/ mp_nexthop %pI6%s",
|
|
|
|
PAF_SUBGRP(paf)->update_group->id,
|
|
|
|
PAF_SUBGRP(paf)->id, peer->host,
|
|
|
|
mod_v6nhg,
|
|
|
|
(nhlen == BGP_ATTR_NHLEN_VPNV6_GLOBAL
|
|
|
|
? " and RD"
|
|
|
|
: ""));
|
2020-02-11 04:03:02 +01:00
|
|
|
}
|
|
|
|
} else if (paf->afi == AFI_L2VPN) {
|
|
|
|
struct in_addr v4nh, *mod_v4nh;
|
|
|
|
int nh_modified = 0;
|
|
|
|
|
|
|
|
stream_get_from(&v4nh, s, vec->offset + 1, 4);
|
|
|
|
mod_v4nh = &v4nh;
|
|
|
|
|
|
|
|
/* No route-map changes allowed for EVPN nexthops. */
|
|
|
|
if (v4nh.s_addr == INADDR_ANY) {
|
|
|
|
mod_v4nh = &peer->nexthop.v4;
|
|
|
|
nh_modified = 1;
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
2020-02-11 04:03:02 +01:00
|
|
|
|
|
|
|
if (nh_modified)
|
|
|
|
stream_put_in_addr_at(s, vec->offset + 1, mod_v4nh);
|
|
|
|
|
|
|
|
if (bgp_debug_update(peer, NULL, NULL, 0))
|
2020-10-15 21:33:09 +02:00
|
|
|
zlog_debug("u%" PRIu64 ":s%" PRIu64
|
|
|
|
" %s send UPDATE w/ nexthop %pI4",
|
2020-02-11 04:03:02 +01:00
|
|
|
PAF_SUBGRP(paf)->update_group->id,
|
2020-10-15 21:33:09 +02:00
|
|
|
PAF_SUBGRP(paf)->id, peer->host, mod_v4nh);
|
2015-05-20 03:03:47 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return s;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Update the vecarr offsets to go beyond 'pos' bytes, i.e. add 'pos'
|
|
|
|
* to each offset.
|
|
|
|
*/
|
|
|
|
static void bpacket_attr_vec_arr_update(struct bpacket_attr_vec_arr *vecarr,
|
|
|
|
size_t pos)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
|
|
|
if (!vecarr)
|
|
|
|
return;
|
|
|
|
|
|
|
|
for (i = 0; i < BGP_ATTR_VEC_MAX; i++)
|
|
|
|
vecarr->entries[i].offset += pos;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Return if there are packets to build for this subgroup.
|
|
|
|
*/
|
2020-03-20 10:57:54 +01:00
|
|
|
bool subgroup_packets_to_build(struct update_subgroup *subgrp)
|
2015-05-20 03:03:47 +02:00
|
|
|
{
|
|
|
|
struct bgp_advertise *adv;
|
|
|
|
|
|
|
|
if (!subgrp)
|
2020-03-20 10:57:54 +01:00
|
|
|
return false;
|
2015-05-20 03:03:47 +02:00
|
|
|
|
2019-04-21 18:17:45 +02:00
|
|
|
adv = bgp_adv_fifo_first(&subgrp->sync->withdraw);
|
2015-05-20 03:03:47 +02:00
|
|
|
if (adv)
|
2020-03-20 10:57:54 +01:00
|
|
|
return true;
|
2015-05-20 03:03:47 +02:00
|
|
|
|
2019-04-21 18:17:45 +02:00
|
|
|
adv = bgp_adv_fifo_first(&subgrp->sync->update);
|
2015-05-20 03:03:47 +02:00
|
|
|
if (adv)
|
2020-03-20 10:57:54 +01:00
|
|
|
return true;
|
2015-05-20 03:03:47 +02:00
|
|
|
|
2020-03-20 10:57:54 +01:00
|
|
|
return false;
|
2015-05-20 03:03:47 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Make BGP update packet. */
|
|
|
|
struct bpacket *subgroup_update_packet(struct update_subgroup *subgrp)
|
|
|
|
{
|
|
|
|
struct bpacket_attr_vec_arr vecarr;
|
|
|
|
struct bpacket *pkt;
|
|
|
|
struct peer *peer;
|
2016-08-10 01:02:03 +02:00
|
|
|
struct stream *s;
|
2015-05-20 03:03:47 +02:00
|
|
|
struct stream *snlri;
|
|
|
|
struct stream *packet;
|
|
|
|
struct bgp_adj_out *adj;
|
BGP: support for addpath TX
Signed-off-by: Daniel Walton <dwalton@cumulusnetworks.com>
Reviewed-by: Donald Sharp <sharpd@cumulusnetworks.com>
Reviewed-by: Vivek Venkataraman <vivek@cumulusnetworks.com
Ticket: CM-8014
This implements addpath TX with the first feature to use it
being "neighbor x.x.x.x addpath-tx-all-paths".
One change to show output is 'show ip bgp x.x.x.x'. If no addpath-tx
features are configured for any peers then everything looks the same
as it is today in that "Advertised to" is at the top and refers to
which peers the bestpath was advertise to.
root@superm-redxp-05[quagga-stash5]# vtysh -c 'show ip bgp 1.1.1.1'
BGP routing table entry for 1.1.1.1/32
Paths: (6 available, best #6, table Default-IP-Routing-Table)
Advertised to non peer-group peers:
r1(10.0.0.1) r2(10.0.0.2) r3(10.0.0.3) r4(10.0.0.4) r5(10.0.0.5) r6(10.0.0.6) r8(10.0.0.8)
Local, (Received from a RR-client)
12.12.12.12 (metric 20) from r2(10.0.0.2) (10.0.0.2)
Origin IGP, metric 0, localpref 100, valid, internal
AddPath ID: RX 0, TX 8
Last update: Fri Oct 30 18:26:44 2015
[snip]
but once you enable an addpath feature we must display "Advertised to" on a path-by-path basis:
superm-redxp-05# show ip bgp 1.1.1.1/32
BGP routing table entry for 1.1.1.1/32
Paths: (6 available, best #6, table Default-IP-Routing-Table)
Local, (Received from a RR-client)
12.12.12.12 (metric 20) from r2(10.0.0.2) (10.0.0.2)
Origin IGP, metric 0, localpref 100, valid, internal
AddPath ID: RX 0, TX 8
Advertised to: r8(10.0.0.8)
Last update: Fri Oct 30 18:26:44 2015
Local, (Received from a RR-client)
34.34.34.34 (metric 20) from r3(10.0.0.3) (10.0.0.3)
Origin IGP, metric 0, localpref 100, valid, internal
AddPath ID: RX 0, TX 7
Advertised to: r8(10.0.0.8)
Last update: Fri Oct 30 18:26:39 2015
Local, (Received from a RR-client)
56.56.56.56 (metric 20) from r6(10.0.0.6) (10.0.0.6)
Origin IGP, metric 0, localpref 100, valid, internal
AddPath ID: RX 0, TX 6
Advertised to: r8(10.0.0.8)
Last update: Fri Oct 30 18:26:39 2015
Local, (Received from a RR-client)
56.56.56.56 (metric 20) from r5(10.0.0.5) (10.0.0.5)
Origin IGP, metric 0, localpref 100, valid, internal
AddPath ID: RX 0, TX 5
Advertised to: r8(10.0.0.8)
Last update: Fri Oct 30 18:26:39 2015
Local, (Received from a RR-client)
34.34.34.34 (metric 20) from r4(10.0.0.4) (10.0.0.4)
Origin IGP, metric 0, localpref 100, valid, internal
AddPath ID: RX 0, TX 4
Advertised to: r8(10.0.0.8)
Last update: Fri Oct 30 18:26:39 2015
Local, (Received from a RR-client)
12.12.12.12 (metric 20) from r1(10.0.0.1) (10.0.0.1)
Origin IGP, metric 0, localpref 100, valid, internal, best
AddPath ID: RX 0, TX 3
Advertised to: r1(10.0.0.1) r2(10.0.0.2) r3(10.0.0.3) r4(10.0.0.4) r5(10.0.0.5) r6(10.0.0.6) r8(10.0.0.8)
Last update: Fri Oct 30 18:26:34 2015
superm-redxp-05#
2015-11-05 18:29:43 +01:00
|
|
|
struct bgp_advertise *adv;
|
2020-03-27 00:11:58 +01:00
|
|
|
struct bgp_dest *dest = NULL;
|
2018-10-03 00:34:03 +02:00
|
|
|
struct bgp_path_info *path = NULL;
|
2015-05-20 03:03:47 +02:00
|
|
|
bgp_size_t total_attr_len = 0;
|
|
|
|
unsigned long attrlen_pos = 0;
|
|
|
|
size_t mpattrlen_pos = 0;
|
|
|
|
size_t mpattr_pos = 0;
|
2016-06-11 20:36:42 +02:00
|
|
|
afi_t afi;
|
|
|
|
safi_t safi;
|
2015-05-20 03:03:47 +02:00
|
|
|
int space_remaining = 0;
|
|
|
|
int space_needed = 0;
|
|
|
|
char send_attr_str[BUFSIZ];
|
|
|
|
int send_attr_printed = 0;
|
2017-06-16 21:12:57 +02:00
|
|
|
int num_pfx = 0;
|
2022-01-27 08:51:59 +01:00
|
|
|
bool addpath_capable = false;
|
2017-07-26 18:33:39 +02:00
|
|
|
int addpath_overhead = 0;
|
2018-03-27 21:13:34 +02:00
|
|
|
uint32_t addpath_tx_id = 0;
|
2017-02-01 19:19:37 +01:00
|
|
|
struct prefix_rd *prd = NULL;
|
2017-11-21 11:42:05 +01:00
|
|
|
mpls_label_t label = MPLS_INVALID_LABEL, *label_pnt = NULL;
|
2024-02-26 18:11:09 +01:00
|
|
|
uint8_t num_labels = 0;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2017-05-15 23:52:17 +02:00
|
|
|
if (!subgrp)
|
2015-05-20 03:03:47 +02:00
|
|
|
return NULL;
|
|
|
|
|
|
|
|
if (bpacket_queue_is_full(SUBGRP_INST(subgrp), SUBGRP_PKTQ(subgrp)))
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
peer = SUBGRP_PEER(subgrp);
|
|
|
|
afi = SUBGRP_AFI(subgrp);
|
|
|
|
safi = SUBGRP_SAFI(subgrp);
|
|
|
|
s = subgrp->work;
|
|
|
|
stream_reset(s);
|
|
|
|
snlri = subgrp->scratch;
|
|
|
|
stream_reset(snlri);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2015-05-20 03:03:47 +02:00
|
|
|
bpacket_attr_vec_arr_reset(&vecarr);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2022-01-27 08:51:59 +01:00
|
|
|
addpath_capable = bgp_addpath_encode_tx(peer, afi, safi);
|
|
|
|
addpath_overhead = addpath_capable ? BGP_ADDPATH_ID_LEN : 0;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2019-04-21 18:17:45 +02:00
|
|
|
adv = bgp_adv_fifo_first(&subgrp->sync->update);
|
2015-05-20 03:03:47 +02:00
|
|
|
while (adv) {
|
2020-03-27 00:11:58 +01:00
|
|
|
const struct prefix *dest_p;
|
2020-03-22 05:02:18 +01:00
|
|
|
|
2020-03-27 00:11:58 +01:00
|
|
|
assert(adv->dest);
|
|
|
|
dest = adv->dest;
|
|
|
|
dest_p = bgp_dest_get_prefix(dest);
|
2015-05-20 03:03:47 +02:00
|
|
|
adj = adv->adj;
|
BGP: support for addpath TX
Signed-off-by: Daniel Walton <dwalton@cumulusnetworks.com>
Reviewed-by: Donald Sharp <sharpd@cumulusnetworks.com>
Reviewed-by: Vivek Venkataraman <vivek@cumulusnetworks.com
Ticket: CM-8014
This implements addpath TX with the first feature to use it
being "neighbor x.x.x.x addpath-tx-all-paths".
One change to show output is 'show ip bgp x.x.x.x'. If no addpath-tx
features are configured for any peers then everything looks the same
as it is today in that "Advertised to" is at the top and refers to
which peers the bestpath was advertise to.
root@superm-redxp-05[quagga-stash5]# vtysh -c 'show ip bgp 1.1.1.1'
BGP routing table entry for 1.1.1.1/32
Paths: (6 available, best #6, table Default-IP-Routing-Table)
Advertised to non peer-group peers:
r1(10.0.0.1) r2(10.0.0.2) r3(10.0.0.3) r4(10.0.0.4) r5(10.0.0.5) r6(10.0.0.6) r8(10.0.0.8)
Local, (Received from a RR-client)
12.12.12.12 (metric 20) from r2(10.0.0.2) (10.0.0.2)
Origin IGP, metric 0, localpref 100, valid, internal
AddPath ID: RX 0, TX 8
Last update: Fri Oct 30 18:26:44 2015
[snip]
but once you enable an addpath feature we must display "Advertised to" on a path-by-path basis:
superm-redxp-05# show ip bgp 1.1.1.1/32
BGP routing table entry for 1.1.1.1/32
Paths: (6 available, best #6, table Default-IP-Routing-Table)
Local, (Received from a RR-client)
12.12.12.12 (metric 20) from r2(10.0.0.2) (10.0.0.2)
Origin IGP, metric 0, localpref 100, valid, internal
AddPath ID: RX 0, TX 8
Advertised to: r8(10.0.0.8)
Last update: Fri Oct 30 18:26:44 2015
Local, (Received from a RR-client)
34.34.34.34 (metric 20) from r3(10.0.0.3) (10.0.0.3)
Origin IGP, metric 0, localpref 100, valid, internal
AddPath ID: RX 0, TX 7
Advertised to: r8(10.0.0.8)
Last update: Fri Oct 30 18:26:39 2015
Local, (Received from a RR-client)
56.56.56.56 (metric 20) from r6(10.0.0.6) (10.0.0.6)
Origin IGP, metric 0, localpref 100, valid, internal
AddPath ID: RX 0, TX 6
Advertised to: r8(10.0.0.8)
Last update: Fri Oct 30 18:26:39 2015
Local, (Received from a RR-client)
56.56.56.56 (metric 20) from r5(10.0.0.5) (10.0.0.5)
Origin IGP, metric 0, localpref 100, valid, internal
AddPath ID: RX 0, TX 5
Advertised to: r8(10.0.0.8)
Last update: Fri Oct 30 18:26:39 2015
Local, (Received from a RR-client)
34.34.34.34 (metric 20) from r4(10.0.0.4) (10.0.0.4)
Origin IGP, metric 0, localpref 100, valid, internal
AddPath ID: RX 0, TX 4
Advertised to: r8(10.0.0.8)
Last update: Fri Oct 30 18:26:39 2015
Local, (Received from a RR-client)
12.12.12.12 (metric 20) from r1(10.0.0.1) (10.0.0.1)
Origin IGP, metric 0, localpref 100, valid, internal, best
AddPath ID: RX 0, TX 3
Advertised to: r1(10.0.0.1) r2(10.0.0.2) r3(10.0.0.3) r4(10.0.0.4) r5(10.0.0.5) r6(10.0.0.6) r8(10.0.0.8)
Last update: Fri Oct 30 18:26:34 2015
superm-redxp-05#
2015-11-05 18:29:43 +01:00
|
|
|
addpath_tx_id = adj->addpath_tx_id;
|
2018-10-03 00:34:03 +02:00
|
|
|
path = adv->pathi;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2015-05-20 03:03:47 +02:00
|
|
|
space_remaining = STREAM_CONCAT_REMAIN(s, snlri, STREAM_SIZE(s))
|
|
|
|
- BGP_MAX_PACKET_SIZE_OVERFLOW;
|
2020-03-27 00:11:58 +01:00
|
|
|
space_needed =
|
|
|
|
BGP_NLRI_LENGTH + addpath_overhead
|
|
|
|
+ bgp_packet_mpattr_prefix_size(afi, safi, dest_p);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2015-05-20 03:03:47 +02:00
|
|
|
/* When remaining space can't include NLRI and it's length. */
|
|
|
|
if (space_remaining < space_needed)
|
2017-07-17 14:03:14 +02:00
|
|
|
break;
|
|
|
|
|
2015-05-20 03:03:47 +02:00
|
|
|
/* If packet is empty, set attribute. */
|
|
|
|
if (stream_empty(s)) {
|
2016-08-10 01:02:03 +02:00
|
|
|
struct peer *from = NULL;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2018-10-03 00:34:03 +02:00
|
|
|
if (path)
|
|
|
|
from = path->peer;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2015-05-20 03:03:47 +02:00
|
|
|
/* 1: Write the BGP message header - 16 bytes marker, 2
|
|
|
|
* bytes length,
|
|
|
|
* one byte message type.
|
2017-07-17 14:03:14 +02:00
|
|
|
*/
|
2015-05-20 03:03:47 +02:00
|
|
|
bgp_packet_set_marker(s, BGP_MSG_UPDATE);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2015-05-20 03:03:47 +02:00
|
|
|
/* 2: withdrawn routes length */
|
|
|
|
stream_putw(s, 0);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2015-05-20 03:03:47 +02:00
|
|
|
/* 3: total attributes length - attrlen_pos stores the
|
|
|
|
* position */
|
|
|
|
attrlen_pos = stream_get_endp(s);
|
|
|
|
stream_putw(s, 0);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2015-05-20 03:03:47 +02:00
|
|
|
/* 4: if there is MP_REACH_NLRI attribute, that should
|
|
|
|
* be the first
|
|
|
|
* attribute, according to
|
|
|
|
* draft-ietf-idr-error-handling. Save the
|
|
|
|
* position.
|
2017-07-17 14:03:14 +02:00
|
|
|
*/
|
2015-05-20 03:03:47 +02:00
|
|
|
mpattr_pos = stream_get_endp(s);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2015-05-20 03:03:47 +02:00
|
|
|
/* 5: Encode all the attributes, except MP_REACH_NLRI
|
|
|
|
* attr. */
|
|
|
|
total_attr_len = bgp_packet_attribute(
|
|
|
|
NULL, peer, s, adv->baa->attr, &vecarr, NULL,
|
2022-10-12 20:06:47 +02:00
|
|
|
afi, safi, from, NULL, NULL, 0, 0, 0, path);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2015-05-20 03:03:47 +02:00
|
|
|
space_remaining =
|
|
|
|
STREAM_CONCAT_REMAIN(s, snlri, STREAM_SIZE(s))
|
|
|
|
- BGP_MAX_PACKET_SIZE_OVERFLOW;
|
2017-07-26 18:33:39 +02:00
|
|
|
space_needed = BGP_NLRI_LENGTH + addpath_overhead
|
|
|
|
+ bgp_packet_mpattr_prefix_size(
|
2020-03-27 00:11:58 +01:00
|
|
|
afi, safi, dest_p);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2015-05-20 03:03:47 +02:00
|
|
|
/* If the attributes alone do not leave any room for
|
|
|
|
* NLRI then
|
|
|
|
* return */
|
|
|
|
if (space_remaining < space_needed) {
|
2018-08-03 20:03:29 +02:00
|
|
|
flog_err(
|
2018-09-13 20:23:42 +02:00
|
|
|
EC_BGP_UPDGRP_ATTR_LEN,
|
2020-03-27 12:51:47 +01:00
|
|
|
"u%" PRIu64 ":s%" PRIu64" attributes too long, cannot send UPDATE",
|
2015-05-20 03:03:47 +02:00
|
|
|
subgrp->update_group->id, subgrp->id);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2015-05-20 03:03:47 +02:00
|
|
|
/* Flush the FIFO update queue */
|
|
|
|
while (adv)
|
|
|
|
adv = bgp_advertise_clean_subgroup(
|
|
|
|
subgrp, adj);
|
|
|
|
return NULL;
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
|
|
|
|
2015-05-20 03:03:47 +02:00
|
|
|
if (BGP_DEBUG(update, UPDATE_OUT)
|
|
|
|
|| BGP_DEBUG(update, UPDATE_PREFIX)) {
|
2017-05-12 14:28:43 +02:00
|
|
|
memset(send_attr_str, 0, BUFSIZ);
|
2015-05-20 03:12:17 +02:00
|
|
|
send_attr_printed = 0;
|
2017-05-12 14:28:43 +02:00
|
|
|
bgp_dump_attr(adv->baa->attr, send_attr_str,
|
2020-08-18 20:43:07 +02:00
|
|
|
sizeof(send_attr_str));
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-05-20 03:03:47 +02:00
|
|
|
if ((afi == AFI_IP && safi == SAFI_UNICAST)
|
2017-05-10 15:40:29 +02:00
|
|
|
&& !peer_cap_enhe(peer, afi, safi))
|
2022-01-27 08:51:59 +01:00
|
|
|
stream_put_prefix_addpath(s, dest_p, addpath_capable,
|
BGP: support for addpath TX
Signed-off-by: Daniel Walton <dwalton@cumulusnetworks.com>
Reviewed-by: Donald Sharp <sharpd@cumulusnetworks.com>
Reviewed-by: Vivek Venkataraman <vivek@cumulusnetworks.com
Ticket: CM-8014
This implements addpath TX with the first feature to use it
being "neighbor x.x.x.x addpath-tx-all-paths".
One change to show output is 'show ip bgp x.x.x.x'. If no addpath-tx
features are configured for any peers then everything looks the same
as it is today in that "Advertised to" is at the top and refers to
which peers the bestpath was advertise to.
root@superm-redxp-05[quagga-stash5]# vtysh -c 'show ip bgp 1.1.1.1'
BGP routing table entry for 1.1.1.1/32
Paths: (6 available, best #6, table Default-IP-Routing-Table)
Advertised to non peer-group peers:
r1(10.0.0.1) r2(10.0.0.2) r3(10.0.0.3) r4(10.0.0.4) r5(10.0.0.5) r6(10.0.0.6) r8(10.0.0.8)
Local, (Received from a RR-client)
12.12.12.12 (metric 20) from r2(10.0.0.2) (10.0.0.2)
Origin IGP, metric 0, localpref 100, valid, internal
AddPath ID: RX 0, TX 8
Last update: Fri Oct 30 18:26:44 2015
[snip]
but once you enable an addpath feature we must display "Advertised to" on a path-by-path basis:
superm-redxp-05# show ip bgp 1.1.1.1/32
BGP routing table entry for 1.1.1.1/32
Paths: (6 available, best #6, table Default-IP-Routing-Table)
Local, (Received from a RR-client)
12.12.12.12 (metric 20) from r2(10.0.0.2) (10.0.0.2)
Origin IGP, metric 0, localpref 100, valid, internal
AddPath ID: RX 0, TX 8
Advertised to: r8(10.0.0.8)
Last update: Fri Oct 30 18:26:44 2015
Local, (Received from a RR-client)
34.34.34.34 (metric 20) from r3(10.0.0.3) (10.0.0.3)
Origin IGP, metric 0, localpref 100, valid, internal
AddPath ID: RX 0, TX 7
Advertised to: r8(10.0.0.8)
Last update: Fri Oct 30 18:26:39 2015
Local, (Received from a RR-client)
56.56.56.56 (metric 20) from r6(10.0.0.6) (10.0.0.6)
Origin IGP, metric 0, localpref 100, valid, internal
AddPath ID: RX 0, TX 6
Advertised to: r8(10.0.0.8)
Last update: Fri Oct 30 18:26:39 2015
Local, (Received from a RR-client)
56.56.56.56 (metric 20) from r5(10.0.0.5) (10.0.0.5)
Origin IGP, metric 0, localpref 100, valid, internal
AddPath ID: RX 0, TX 5
Advertised to: r8(10.0.0.8)
Last update: Fri Oct 30 18:26:39 2015
Local, (Received from a RR-client)
34.34.34.34 (metric 20) from r4(10.0.0.4) (10.0.0.4)
Origin IGP, metric 0, localpref 100, valid, internal
AddPath ID: RX 0, TX 4
Advertised to: r8(10.0.0.8)
Last update: Fri Oct 30 18:26:39 2015
Local, (Received from a RR-client)
12.12.12.12 (metric 20) from r1(10.0.0.1) (10.0.0.1)
Origin IGP, metric 0, localpref 100, valid, internal, best
AddPath ID: RX 0, TX 3
Advertised to: r1(10.0.0.1) r2(10.0.0.2) r3(10.0.0.3) r4(10.0.0.4) r5(10.0.0.5) r6(10.0.0.6) r8(10.0.0.8)
Last update: Fri Oct 30 18:26:34 2015
superm-redxp-05#
2015-11-05 18:29:43 +01:00
|
|
|
addpath_tx_id);
|
2017-07-17 14:03:14 +02:00
|
|
|
else {
|
2015-05-20 03:03:47 +02:00
|
|
|
/* Encode the prefix in MP_REACH_NLRI attribute */
|
2020-03-27 00:11:58 +01:00
|
|
|
if (dest->pdest)
|
|
|
|
prd = (struct prefix_rd *)bgp_dest_get_prefix(
|
|
|
|
dest->pdest);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2017-11-21 11:42:05 +01:00
|
|
|
if (safi == SAFI_LABELED_UNICAST) {
|
2020-03-27 00:11:58 +01:00
|
|
|
label = bgp_adv_label(dest, path, peer, afi,
|
2017-07-17 14:03:14 +02:00
|
|
|
safi);
|
2017-11-21 11:42:05 +01:00
|
|
|
label_pnt = &label;
|
|
|
|
num_labels = 1;
|
2023-05-11 15:26:50 +02:00
|
|
|
} else if (safi == SAFI_MPLS_VPN && path &&
|
|
|
|
CHECK_FLAG(path->flags,
|
|
|
|
BGP_PATH_MPLSVPN_NH_LABEL_BIND) &&
|
|
|
|
path->mplsvpn.bmnc.nh_label_bind_cache &&
|
|
|
|
path->peer && path->peer != peer &&
|
|
|
|
path->sub_type != BGP_ROUTE_IMPORTED &&
|
|
|
|
path->sub_type != BGP_ROUTE_STATIC &&
|
|
|
|
bgp_mplsvpn_path_uses_valid_mpls_label(
|
|
|
|
path) &&
|
|
|
|
bgp_path_info_nexthop_changed(path, peer,
|
|
|
|
afi)) {
|
|
|
|
/* Redistributed mpls vpn route between distinct
|
|
|
|
* peers from 'pi->peer' to 'to',
|
|
|
|
* and an mpls label is used in this path,
|
|
|
|
* and there is a nh label bind entry,
|
|
|
|
* then get appropriate mpls local label. When
|
|
|
|
* called here, 'get_label()' returns a valid
|
|
|
|
* label.
|
|
|
|
*/
|
|
|
|
label = bgp_mplsvpn_nh_label_bind_get_label(
|
|
|
|
path);
|
|
|
|
label_pnt = &label;
|
|
|
|
num_labels = 1;
|
2024-02-26 10:42:42 +01:00
|
|
|
} else {
|
|
|
|
num_labels = bgp_path_info_num_labels(path);
|
2024-02-26 18:23:11 +01:00
|
|
|
label_pnt =
|
|
|
|
num_labels
|
|
|
|
? &path->extra->labels->label[0]
|
|
|
|
: NULL;
|
2017-11-21 11:42:05 +01:00
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2015-05-20 03:03:47 +02:00
|
|
|
if (stream_empty(snlri))
|
|
|
|
mpattrlen_pos = bgp_packet_mpattr_start(
|
2017-05-16 19:28:12 +02:00
|
|
|
snlri, peer, afi, safi, &vecarr,
|
2015-05-20 03:03:47 +02:00
|
|
|
adv->baa->attr);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2020-03-27 00:11:58 +01:00
|
|
|
bgp_packet_mpattr_prefix(snlri, afi, safi, dest_p, prd,
|
2017-11-21 11:42:05 +01:00
|
|
|
label_pnt, num_labels,
|
2022-01-27 08:51:59 +01:00
|
|
|
addpath_capable, addpath_tx_id,
|
2017-11-21 11:42:05 +01:00
|
|
|
adv->baa->attr);
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
|
|
|
|
2015-05-20 03:03:47 +02:00
|
|
|
num_pfx++;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2020-03-27 00:11:58 +01:00
|
|
|
if (bgp_debug_update(NULL, dest_p, subgrp->update_group, 0)) {
|
2016-08-10 01:02:03 +02:00
|
|
|
char pfx_buf[BGP_PRD_PATH_STRLEN];
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2015-05-20 03:03:47 +02:00
|
|
|
if (!send_attr_printed) {
|
2020-03-27 12:51:47 +01:00
|
|
|
zlog_debug("u%" PRIu64 ":s%" PRIu64" send UPDATE w/ attr: %s",
|
2015-05-20 03:03:47 +02:00
|
|
|
subgrp->update_group->id, subgrp->id,
|
|
|
|
send_attr_str);
|
|
|
|
if (!stream_empty(snlri)) {
|
2017-03-15 20:12:47 +01:00
|
|
|
iana_afi_t pkt_afi;
|
2017-08-01 02:06:40 +02:00
|
|
|
iana_safi_t pkt_safi;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2017-02-01 19:19:37 +01:00
|
|
|
pkt_afi = afi_int2iana(afi);
|
|
|
|
pkt_safi = safi_int2iana(safi);
|
2017-05-15 23:52:17 +02:00
|
|
|
zlog_debug(
|
2020-12-11 10:44:38 +01:00
|
|
|
"u%" PRIu64 ":s%" PRIu64
|
|
|
|
" send MP_REACH for afi/safi %s/%s",
|
2017-05-15 23:52:17 +02:00
|
|
|
subgrp->update_group->id,
|
2020-12-11 10:44:38 +01:00
|
|
|
subgrp->id,
|
|
|
|
iana_afi2str(pkt_afi),
|
|
|
|
iana_safi2str(pkt_safi));
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
|
|
|
|
2015-05-20 03:03:47 +02:00
|
|
|
send_attr_printed = 1;
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
|
|
|
|
2020-03-27 00:11:58 +01:00
|
|
|
bgp_debug_rdpfxpath2str(afi, safi, prd, dest_p,
|
|
|
|
label_pnt, num_labels,
|
2022-01-27 08:51:59 +01:00
|
|
|
addpath_capable, addpath_tx_id,
|
2024-08-11 12:59:13 +02:00
|
|
|
bgp_attr_get_evpn_overlay(
|
|
|
|
adv->baa->attr),
|
2020-03-27 00:11:58 +01:00
|
|
|
pfx_buf, sizeof(pfx_buf));
|
2017-05-15 23:52:17 +02:00
|
|
|
zlog_debug("u%" PRIu64 ":s%" PRIu64 " send UPDATE %s",
|
2017-02-01 19:19:37 +01:00
|
|
|
subgrp->update_group->id, subgrp->id,
|
2017-05-15 23:52:17 +02:00
|
|
|
pfx_buf);
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
|
|
|
|
2015-05-20 03:03:47 +02:00
|
|
|
/* Synchnorize attribute. */
|
|
|
|
if (adj->attr)
|
|
|
|
bgp_attr_unintern(&adj->attr);
|
2017-07-17 14:03:14 +02:00
|
|
|
else
|
2015-05-20 03:03:47 +02:00
|
|
|
subgrp->scount++;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2015-05-20 03:03:47 +02:00
|
|
|
adj->attr = bgp_attr_intern(adv->baa->attr);
|
|
|
|
adv = bgp_advertise_clean_subgroup(subgrp, adj);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!stream_empty(s)) {
|
2017-02-01 19:19:37 +01:00
|
|
|
if (!stream_empty(snlri)) {
|
2017-05-16 19:28:12 +02:00
|
|
|
bgp_packet_mpattr_end(snlri, mpattrlen_pos);
|
2015-05-20 03:03:47 +02:00
|
|
|
total_attr_len += stream_get_endp(snlri);
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
|
|
|
|
2015-05-20 03:03:47 +02:00
|
|
|
/* set the total attribute length correctly */
|
|
|
|
stream_putw_at(s, attrlen_pos, total_attr_len);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2015-05-20 03:03:47 +02:00
|
|
|
if (!stream_empty(snlri)) {
|
|
|
|
packet = stream_dupcat(s, snlri, mpattr_pos);
|
|
|
|
bpacket_attr_vec_arr_update(&vecarr, mpattr_pos);
|
2017-07-17 14:03:14 +02:00
|
|
|
} else
|
2015-05-20 03:03:47 +02:00
|
|
|
packet = stream_dup(s);
|
|
|
|
bgp_packet_set_size(packet);
|
|
|
|
if (bgp_debug_update(NULL, NULL, subgrp->update_group, 0))
|
2021-02-25 18:46:49 +01:00
|
|
|
zlog_debug(
|
|
|
|
"u%" PRIu64 ":s%" PRIu64
|
|
|
|
" send UPDATE len %zd (max message len: %hu) numpfx %d",
|
|
|
|
subgrp->update_group->id, subgrp->id,
|
|
|
|
(stream_get_endp(packet)
|
|
|
|
- stream_get_getp(packet)),
|
|
|
|
peer->max_packet_size, num_pfx);
|
2015-05-20 03:03:47 +02:00
|
|
|
pkt = bpacket_queue_add(SUBGRP_PKTQ(subgrp), packet, &vecarr);
|
|
|
|
stream_reset(s);
|
|
|
|
stream_reset(snlri);
|
|
|
|
return pkt;
|
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Make BGP withdraw packet. */
|
|
|
|
/* For ipv4 unicast:
|
|
|
|
16-octet marker | 2-octet length | 1-octet type |
|
|
|
|
2-octet withdrawn route length | withdrawn prefixes | 2-octet attrlen (=0)
|
|
|
|
*/
|
|
|
|
/* For other afi/safis:
|
|
|
|
16-octet marker | 2-octet length | 1-octet type |
|
|
|
|
2-octet withdrawn route length (=0) | 2-octet attrlen |
|
|
|
|
mp_unreach attr type | attr len | afi | safi | withdrawn prefixes
|
|
|
|
*/
|
|
|
|
struct bpacket *subgroup_withdraw_packet(struct update_subgroup *subgrp)
|
|
|
|
{
|
|
|
|
struct bpacket *pkt;
|
|
|
|
struct stream *s;
|
|
|
|
struct bgp_adj_out *adj;
|
|
|
|
struct bgp_advertise *adv;
|
2016-08-10 01:02:03 +02:00
|
|
|
struct peer *peer;
|
2020-03-27 00:11:58 +01:00
|
|
|
struct bgp_dest *dest;
|
2015-05-20 03:03:47 +02:00
|
|
|
bgp_size_t unfeasible_len;
|
BGP: support for addpath TX
Signed-off-by: Daniel Walton <dwalton@cumulusnetworks.com>
Reviewed-by: Donald Sharp <sharpd@cumulusnetworks.com>
Reviewed-by: Vivek Venkataraman <vivek@cumulusnetworks.com
Ticket: CM-8014
This implements addpath TX with the first feature to use it
being "neighbor x.x.x.x addpath-tx-all-paths".
One change to show output is 'show ip bgp x.x.x.x'. If no addpath-tx
features are configured for any peers then everything looks the same
as it is today in that "Advertised to" is at the top and refers to
which peers the bestpath was advertise to.
root@superm-redxp-05[quagga-stash5]# vtysh -c 'show ip bgp 1.1.1.1'
BGP routing table entry for 1.1.1.1/32
Paths: (6 available, best #6, table Default-IP-Routing-Table)
Advertised to non peer-group peers:
r1(10.0.0.1) r2(10.0.0.2) r3(10.0.0.3) r4(10.0.0.4) r5(10.0.0.5) r6(10.0.0.6) r8(10.0.0.8)
Local, (Received from a RR-client)
12.12.12.12 (metric 20) from r2(10.0.0.2) (10.0.0.2)
Origin IGP, metric 0, localpref 100, valid, internal
AddPath ID: RX 0, TX 8
Last update: Fri Oct 30 18:26:44 2015
[snip]
but once you enable an addpath feature we must display "Advertised to" on a path-by-path basis:
superm-redxp-05# show ip bgp 1.1.1.1/32
BGP routing table entry for 1.1.1.1/32
Paths: (6 available, best #6, table Default-IP-Routing-Table)
Local, (Received from a RR-client)
12.12.12.12 (metric 20) from r2(10.0.0.2) (10.0.0.2)
Origin IGP, metric 0, localpref 100, valid, internal
AddPath ID: RX 0, TX 8
Advertised to: r8(10.0.0.8)
Last update: Fri Oct 30 18:26:44 2015
Local, (Received from a RR-client)
34.34.34.34 (metric 20) from r3(10.0.0.3) (10.0.0.3)
Origin IGP, metric 0, localpref 100, valid, internal
AddPath ID: RX 0, TX 7
Advertised to: r8(10.0.0.8)
Last update: Fri Oct 30 18:26:39 2015
Local, (Received from a RR-client)
56.56.56.56 (metric 20) from r6(10.0.0.6) (10.0.0.6)
Origin IGP, metric 0, localpref 100, valid, internal
AddPath ID: RX 0, TX 6
Advertised to: r8(10.0.0.8)
Last update: Fri Oct 30 18:26:39 2015
Local, (Received from a RR-client)
56.56.56.56 (metric 20) from r5(10.0.0.5) (10.0.0.5)
Origin IGP, metric 0, localpref 100, valid, internal
AddPath ID: RX 0, TX 5
Advertised to: r8(10.0.0.8)
Last update: Fri Oct 30 18:26:39 2015
Local, (Received from a RR-client)
34.34.34.34 (metric 20) from r4(10.0.0.4) (10.0.0.4)
Origin IGP, metric 0, localpref 100, valid, internal
AddPath ID: RX 0, TX 4
Advertised to: r8(10.0.0.8)
Last update: Fri Oct 30 18:26:39 2015
Local, (Received from a RR-client)
12.12.12.12 (metric 20) from r1(10.0.0.1) (10.0.0.1)
Origin IGP, metric 0, localpref 100, valid, internal, best
AddPath ID: RX 0, TX 3
Advertised to: r1(10.0.0.1) r2(10.0.0.2) r3(10.0.0.3) r4(10.0.0.4) r5(10.0.0.5) r6(10.0.0.6) r8(10.0.0.8)
Last update: Fri Oct 30 18:26:34 2015
superm-redxp-05#
2015-11-05 18:29:43 +01:00
|
|
|
bgp_size_t total_attr_len;
|
|
|
|
size_t mp_start = 0;
|
2016-06-11 20:36:42 +02:00
|
|
|
size_t attrlen_pos = 0;
|
|
|
|
size_t mplen_pos = 0;
|
2018-03-27 21:13:34 +02:00
|
|
|
uint8_t first_time = 1;
|
2015-05-20 03:03:47 +02:00
|
|
|
afi_t afi;
|
2016-06-11 20:36:42 +02:00
|
|
|
safi_t safi;
|
2015-05-20 03:03:47 +02:00
|
|
|
int space_remaining = 0;
|
|
|
|
int space_needed = 0;
|
|
|
|
int num_pfx = 0;
|
2022-01-27 08:51:59 +01:00
|
|
|
bool addpath_capable = false;
|
2017-07-26 18:33:39 +02:00
|
|
|
int addpath_overhead = 0;
|
2018-03-27 21:13:34 +02:00
|
|
|
uint32_t addpath_tx_id = 0;
|
2020-03-22 05:02:18 +01:00
|
|
|
const struct prefix_rd *prd = NULL;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
|
|
|
|
2017-02-01 19:19:37 +01:00
|
|
|
if (!subgrp)
|
BGP: support for addpath TX
Signed-off-by: Daniel Walton <dwalton@cumulusnetworks.com>
Reviewed-by: Donald Sharp <sharpd@cumulusnetworks.com>
Reviewed-by: Vivek Venkataraman <vivek@cumulusnetworks.com
Ticket: CM-8014
This implements addpath TX with the first feature to use it
being "neighbor x.x.x.x addpath-tx-all-paths".
One change to show output is 'show ip bgp x.x.x.x'. If no addpath-tx
features are configured for any peers then everything looks the same
as it is today in that "Advertised to" is at the top and refers to
which peers the bestpath was advertise to.
root@superm-redxp-05[quagga-stash5]# vtysh -c 'show ip bgp 1.1.1.1'
BGP routing table entry for 1.1.1.1/32
Paths: (6 available, best #6, table Default-IP-Routing-Table)
Advertised to non peer-group peers:
r1(10.0.0.1) r2(10.0.0.2) r3(10.0.0.3) r4(10.0.0.4) r5(10.0.0.5) r6(10.0.0.6) r8(10.0.0.8)
Local, (Received from a RR-client)
12.12.12.12 (metric 20) from r2(10.0.0.2) (10.0.0.2)
Origin IGP, metric 0, localpref 100, valid, internal
AddPath ID: RX 0, TX 8
Last update: Fri Oct 30 18:26:44 2015
[snip]
but once you enable an addpath feature we must display "Advertised to" on a path-by-path basis:
superm-redxp-05# show ip bgp 1.1.1.1/32
BGP routing table entry for 1.1.1.1/32
Paths: (6 available, best #6, table Default-IP-Routing-Table)
Local, (Received from a RR-client)
12.12.12.12 (metric 20) from r2(10.0.0.2) (10.0.0.2)
Origin IGP, metric 0, localpref 100, valid, internal
AddPath ID: RX 0, TX 8
Advertised to: r8(10.0.0.8)
Last update: Fri Oct 30 18:26:44 2015
Local, (Received from a RR-client)
34.34.34.34 (metric 20) from r3(10.0.0.3) (10.0.0.3)
Origin IGP, metric 0, localpref 100, valid, internal
AddPath ID: RX 0, TX 7
Advertised to: r8(10.0.0.8)
Last update: Fri Oct 30 18:26:39 2015
Local, (Received from a RR-client)
56.56.56.56 (metric 20) from r6(10.0.0.6) (10.0.0.6)
Origin IGP, metric 0, localpref 100, valid, internal
AddPath ID: RX 0, TX 6
Advertised to: r8(10.0.0.8)
Last update: Fri Oct 30 18:26:39 2015
Local, (Received from a RR-client)
56.56.56.56 (metric 20) from r5(10.0.0.5) (10.0.0.5)
Origin IGP, metric 0, localpref 100, valid, internal
AddPath ID: RX 0, TX 5
Advertised to: r8(10.0.0.8)
Last update: Fri Oct 30 18:26:39 2015
Local, (Received from a RR-client)
34.34.34.34 (metric 20) from r4(10.0.0.4) (10.0.0.4)
Origin IGP, metric 0, localpref 100, valid, internal
AddPath ID: RX 0, TX 4
Advertised to: r8(10.0.0.8)
Last update: Fri Oct 30 18:26:39 2015
Local, (Received from a RR-client)
12.12.12.12 (metric 20) from r1(10.0.0.1) (10.0.0.1)
Origin IGP, metric 0, localpref 100, valid, internal, best
AddPath ID: RX 0, TX 3
Advertised to: r1(10.0.0.1) r2(10.0.0.2) r3(10.0.0.3) r4(10.0.0.4) r5(10.0.0.5) r6(10.0.0.6) r8(10.0.0.8)
Last update: Fri Oct 30 18:26:34 2015
superm-redxp-05#
2015-11-05 18:29:43 +01:00
|
|
|
return NULL;
|
2015-05-20 03:03:47 +02:00
|
|
|
|
|
|
|
if (bpacket_queue_is_full(SUBGRP_INST(subgrp), SUBGRP_PKTQ(subgrp)))
|
|
|
|
return NULL;
|
2016-08-10 01:02:03 +02:00
|
|
|
|
2017-05-15 23:52:17 +02:00
|
|
|
peer = SUBGRP_PEER(subgrp);
|
2015-05-20 03:03:47 +02:00
|
|
|
afi = SUBGRP_AFI(subgrp);
|
|
|
|
safi = SUBGRP_SAFI(subgrp);
|
|
|
|
s = subgrp->work;
|
|
|
|
stream_reset(s);
|
2022-01-27 08:51:59 +01:00
|
|
|
addpath_capable = bgp_addpath_encode_tx(peer, afi, safi);
|
|
|
|
addpath_overhead = addpath_capable ? BGP_ADDPATH_ID_LEN : 0;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2019-04-21 18:17:45 +02:00
|
|
|
while ((adv = bgp_adv_fifo_first(&subgrp->sync->withdraw)) != NULL) {
|
2020-03-27 00:11:58 +01:00
|
|
|
const struct prefix *dest_p;
|
2020-03-22 05:02:18 +01:00
|
|
|
|
2020-03-27 00:11:58 +01:00
|
|
|
assert(adv->dest);
|
2015-05-20 03:03:47 +02:00
|
|
|
adj = adv->adj;
|
2020-03-27 00:11:58 +01:00
|
|
|
dest = adv->dest;
|
|
|
|
dest_p = bgp_dest_get_prefix(dest);
|
BGP: support for addpath TX
Signed-off-by: Daniel Walton <dwalton@cumulusnetworks.com>
Reviewed-by: Donald Sharp <sharpd@cumulusnetworks.com>
Reviewed-by: Vivek Venkataraman <vivek@cumulusnetworks.com
Ticket: CM-8014
This implements addpath TX with the first feature to use it
being "neighbor x.x.x.x addpath-tx-all-paths".
One change to show output is 'show ip bgp x.x.x.x'. If no addpath-tx
features are configured for any peers then everything looks the same
as it is today in that "Advertised to" is at the top and refers to
which peers the bestpath was advertise to.
root@superm-redxp-05[quagga-stash5]# vtysh -c 'show ip bgp 1.1.1.1'
BGP routing table entry for 1.1.1.1/32
Paths: (6 available, best #6, table Default-IP-Routing-Table)
Advertised to non peer-group peers:
r1(10.0.0.1) r2(10.0.0.2) r3(10.0.0.3) r4(10.0.0.4) r5(10.0.0.5) r6(10.0.0.6) r8(10.0.0.8)
Local, (Received from a RR-client)
12.12.12.12 (metric 20) from r2(10.0.0.2) (10.0.0.2)
Origin IGP, metric 0, localpref 100, valid, internal
AddPath ID: RX 0, TX 8
Last update: Fri Oct 30 18:26:44 2015
[snip]
but once you enable an addpath feature we must display "Advertised to" on a path-by-path basis:
superm-redxp-05# show ip bgp 1.1.1.1/32
BGP routing table entry for 1.1.1.1/32
Paths: (6 available, best #6, table Default-IP-Routing-Table)
Local, (Received from a RR-client)
12.12.12.12 (metric 20) from r2(10.0.0.2) (10.0.0.2)
Origin IGP, metric 0, localpref 100, valid, internal
AddPath ID: RX 0, TX 8
Advertised to: r8(10.0.0.8)
Last update: Fri Oct 30 18:26:44 2015
Local, (Received from a RR-client)
34.34.34.34 (metric 20) from r3(10.0.0.3) (10.0.0.3)
Origin IGP, metric 0, localpref 100, valid, internal
AddPath ID: RX 0, TX 7
Advertised to: r8(10.0.0.8)
Last update: Fri Oct 30 18:26:39 2015
Local, (Received from a RR-client)
56.56.56.56 (metric 20) from r6(10.0.0.6) (10.0.0.6)
Origin IGP, metric 0, localpref 100, valid, internal
AddPath ID: RX 0, TX 6
Advertised to: r8(10.0.0.8)
Last update: Fri Oct 30 18:26:39 2015
Local, (Received from a RR-client)
56.56.56.56 (metric 20) from r5(10.0.0.5) (10.0.0.5)
Origin IGP, metric 0, localpref 100, valid, internal
AddPath ID: RX 0, TX 5
Advertised to: r8(10.0.0.8)
Last update: Fri Oct 30 18:26:39 2015
Local, (Received from a RR-client)
34.34.34.34 (metric 20) from r4(10.0.0.4) (10.0.0.4)
Origin IGP, metric 0, localpref 100, valid, internal
AddPath ID: RX 0, TX 4
Advertised to: r8(10.0.0.8)
Last update: Fri Oct 30 18:26:39 2015
Local, (Received from a RR-client)
12.12.12.12 (metric 20) from r1(10.0.0.1) (10.0.0.1)
Origin IGP, metric 0, localpref 100, valid, internal, best
AddPath ID: RX 0, TX 3
Advertised to: r1(10.0.0.1) r2(10.0.0.2) r3(10.0.0.3) r4(10.0.0.4) r5(10.0.0.5) r6(10.0.0.6) r8(10.0.0.8)
Last update: Fri Oct 30 18:26:34 2015
superm-redxp-05#
2015-11-05 18:29:43 +01:00
|
|
|
addpath_tx_id = adj->addpath_tx_id;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2015-05-20 03:03:47 +02:00
|
|
|
space_remaining =
|
2017-11-08 18:51:16 +01:00
|
|
|
STREAM_WRITEABLE(s) - BGP_MAX_PACKET_SIZE_OVERFLOW;
|
2020-03-27 00:11:58 +01:00
|
|
|
space_needed =
|
|
|
|
BGP_NLRI_LENGTH + addpath_overhead + BGP_TOTAL_ATTR_LEN
|
|
|
|
+ bgp_packet_mpattr_prefix_size(afi, safi, dest_p);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2015-05-20 03:03:47 +02:00
|
|
|
if (space_remaining < space_needed)
|
2017-07-17 14:03:14 +02:00
|
|
|
break;
|
|
|
|
|
2015-05-20 03:03:47 +02:00
|
|
|
if (stream_empty(s)) {
|
|
|
|
bgp_packet_set_marker(s, BGP_MSG_UPDATE);
|
|
|
|
stream_putw(s, 0); /* unfeasible routes length */
|
2017-07-17 14:03:14 +02:00
|
|
|
} else
|
2015-05-20 03:03:47 +02:00
|
|
|
first_time = 0;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2015-06-11 18:19:12 +02:00
|
|
|
if (afi == AFI_IP && safi == SAFI_UNICAST
|
2017-05-10 15:40:29 +02:00
|
|
|
&& !peer_cap_enhe(peer, afi, safi))
|
2022-01-27 08:51:59 +01:00
|
|
|
stream_put_prefix_addpath(s, dest_p, addpath_capable,
|
BGP: support for addpath TX
Signed-off-by: Daniel Walton <dwalton@cumulusnetworks.com>
Reviewed-by: Donald Sharp <sharpd@cumulusnetworks.com>
Reviewed-by: Vivek Venkataraman <vivek@cumulusnetworks.com
Ticket: CM-8014
This implements addpath TX with the first feature to use it
being "neighbor x.x.x.x addpath-tx-all-paths".
One change to show output is 'show ip bgp x.x.x.x'. If no addpath-tx
features are configured for any peers then everything looks the same
as it is today in that "Advertised to" is at the top and refers to
which peers the bestpath was advertise to.
root@superm-redxp-05[quagga-stash5]# vtysh -c 'show ip bgp 1.1.1.1'
BGP routing table entry for 1.1.1.1/32
Paths: (6 available, best #6, table Default-IP-Routing-Table)
Advertised to non peer-group peers:
r1(10.0.0.1) r2(10.0.0.2) r3(10.0.0.3) r4(10.0.0.4) r5(10.0.0.5) r6(10.0.0.6) r8(10.0.0.8)
Local, (Received from a RR-client)
12.12.12.12 (metric 20) from r2(10.0.0.2) (10.0.0.2)
Origin IGP, metric 0, localpref 100, valid, internal
AddPath ID: RX 0, TX 8
Last update: Fri Oct 30 18:26:44 2015
[snip]
but once you enable an addpath feature we must display "Advertised to" on a path-by-path basis:
superm-redxp-05# show ip bgp 1.1.1.1/32
BGP routing table entry for 1.1.1.1/32
Paths: (6 available, best #6, table Default-IP-Routing-Table)
Local, (Received from a RR-client)
12.12.12.12 (metric 20) from r2(10.0.0.2) (10.0.0.2)
Origin IGP, metric 0, localpref 100, valid, internal
AddPath ID: RX 0, TX 8
Advertised to: r8(10.0.0.8)
Last update: Fri Oct 30 18:26:44 2015
Local, (Received from a RR-client)
34.34.34.34 (metric 20) from r3(10.0.0.3) (10.0.0.3)
Origin IGP, metric 0, localpref 100, valid, internal
AddPath ID: RX 0, TX 7
Advertised to: r8(10.0.0.8)
Last update: Fri Oct 30 18:26:39 2015
Local, (Received from a RR-client)
56.56.56.56 (metric 20) from r6(10.0.0.6) (10.0.0.6)
Origin IGP, metric 0, localpref 100, valid, internal
AddPath ID: RX 0, TX 6
Advertised to: r8(10.0.0.8)
Last update: Fri Oct 30 18:26:39 2015
Local, (Received from a RR-client)
56.56.56.56 (metric 20) from r5(10.0.0.5) (10.0.0.5)
Origin IGP, metric 0, localpref 100, valid, internal
AddPath ID: RX 0, TX 5
Advertised to: r8(10.0.0.8)
Last update: Fri Oct 30 18:26:39 2015
Local, (Received from a RR-client)
34.34.34.34 (metric 20) from r4(10.0.0.4) (10.0.0.4)
Origin IGP, metric 0, localpref 100, valid, internal
AddPath ID: RX 0, TX 4
Advertised to: r8(10.0.0.8)
Last update: Fri Oct 30 18:26:39 2015
Local, (Received from a RR-client)
12.12.12.12 (metric 20) from r1(10.0.0.1) (10.0.0.1)
Origin IGP, metric 0, localpref 100, valid, internal, best
AddPath ID: RX 0, TX 3
Advertised to: r1(10.0.0.1) r2(10.0.0.2) r3(10.0.0.3) r4(10.0.0.4) r5(10.0.0.5) r6(10.0.0.6) r8(10.0.0.8)
Last update: Fri Oct 30 18:26:34 2015
superm-redxp-05#
2015-11-05 18:29:43 +01:00
|
|
|
addpath_tx_id);
|
2017-07-17 14:03:14 +02:00
|
|
|
else {
|
2020-03-27 00:11:58 +01:00
|
|
|
if (dest->pdest)
|
|
|
|
prd = (struct prefix_rd *)bgp_dest_get_prefix(
|
|
|
|
dest->pdest);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2020-03-22 05:02:18 +01:00
|
|
|
/* If first time, format the MP_UNREACH header
|
|
|
|
*/
|
2015-05-20 03:03:47 +02:00
|
|
|
if (first_time) {
|
2017-03-15 20:12:47 +01:00
|
|
|
iana_afi_t pkt_afi;
|
2017-08-01 02:06:40 +02:00
|
|
|
iana_safi_t pkt_safi;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2017-02-01 19:19:37 +01:00
|
|
|
pkt_afi = afi_int2iana(afi);
|
|
|
|
pkt_safi = safi_int2iana(safi);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2015-05-20 03:03:47 +02:00
|
|
|
attrlen_pos = stream_get_endp(s);
|
2020-03-22 05:02:18 +01:00
|
|
|
/* total attr length = 0 for now.
|
|
|
|
* reevaluate later */
|
2015-05-20 03:03:47 +02:00
|
|
|
stream_putw(s, 0);
|
|
|
|
mp_start = stream_get_endp(s);
|
|
|
|
mplen_pos = bgp_packet_mpunreach_start(s, afi,
|
2017-07-17 14:03:14 +02:00
|
|
|
safi);
|
2015-05-20 03:03:47 +02:00
|
|
|
if (bgp_debug_update(NULL, NULL,
|
|
|
|
subgrp->update_group, 0))
|
2017-02-01 19:19:37 +01:00
|
|
|
zlog_debug(
|
2020-12-11 10:44:38 +01:00
|
|
|
"u%" PRIu64 ":s%" PRIu64
|
|
|
|
" send MP_UNREACH for afi/safi %s/%s",
|
2017-02-01 19:19:37 +01:00
|
|
|
subgrp->update_group->id,
|
2020-12-11 10:44:38 +01:00
|
|
|
subgrp->id,
|
|
|
|
iana_afi2str(pkt_afi),
|
|
|
|
iana_safi2str(pkt_safi));
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
|
|
|
|
2020-03-27 00:11:58 +01:00
|
|
|
bgp_packet_mpunreach_prefix(s, dest_p, afi, safi, prd,
|
2022-01-27 08:51:59 +01:00
|
|
|
NULL, 0, addpath_capable,
|
2016-09-05 14:19:40 +02:00
|
|
|
addpath_tx_id, NULL);
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
|
|
|
|
2015-05-20 03:03:47 +02:00
|
|
|
num_pfx++;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2020-03-27 00:11:58 +01:00
|
|
|
if (bgp_debug_update(NULL, dest_p, subgrp->update_group, 0)) {
|
2016-08-10 01:02:03 +02:00
|
|
|
char pfx_buf[BGP_PRD_PATH_STRLEN];
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2020-03-27 00:11:58 +01:00
|
|
|
bgp_debug_rdpfxpath2str(afi, safi, prd, dest_p, NULL, 0,
|
2022-01-27 08:51:59 +01:00
|
|
|
addpath_capable, addpath_tx_id,
|
2021-01-11 03:32:34 +01:00
|
|
|
NULL, pfx_buf, sizeof(pfx_buf));
|
2020-03-27 12:51:47 +01:00
|
|
|
zlog_debug("u%" PRIu64 ":s%" PRIu64" send UPDATE %s -- unreachable",
|
2017-05-15 23:52:17 +02:00
|
|
|
subgrp->update_group->id, subgrp->id,
|
|
|
|
pfx_buf);
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
|
|
|
|
2015-05-20 03:03:47 +02:00
|
|
|
subgrp->scount--;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2020-03-27 00:11:58 +01:00
|
|
|
bgp_adj_out_remove_subgroup(dest, adj, subgrp);
|
2015-05-20 03:03:47 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if (!stream_empty(s)) {
|
2015-06-11 18:19:12 +02:00
|
|
|
if (afi == AFI_IP && safi == SAFI_UNICAST
|
2017-05-10 15:40:29 +02:00
|
|
|
&& !peer_cap_enhe(peer, afi, safi)) {
|
2015-05-20 03:03:47 +02:00
|
|
|
unfeasible_len = stream_get_endp(s) - BGP_HEADER_SIZE
|
|
|
|
- BGP_UNFEASIBLE_LEN;
|
|
|
|
stream_putw_at(s, BGP_HEADER_SIZE, unfeasible_len);
|
|
|
|
stream_putw(s, 0);
|
|
|
|
} else {
|
|
|
|
/* Set the mp_unreach attr's length */
|
|
|
|
bgp_packet_mpunreach_end(s, mplen_pos);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2015-05-20 03:03:47 +02:00
|
|
|
/* Set total path attribute length. */
|
|
|
|
total_attr_len = stream_get_endp(s) - mp_start;
|
|
|
|
stream_putw_at(s, attrlen_pos, total_attr_len);
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
2015-05-20 03:03:47 +02:00
|
|
|
bgp_packet_set_size(s);
|
|
|
|
if (bgp_debug_update(NULL, NULL, subgrp->update_group, 0))
|
2020-03-27 12:51:47 +01:00
|
|
|
zlog_debug("u%" PRIu64 ":s%" PRIu64" send UPDATE (withdraw) len %zd numpfx %d",
|
2015-05-20 03:03:47 +02:00
|
|
|
subgrp->update_group->id, subgrp->id,
|
|
|
|
(stream_get_endp(s) - stream_get_getp(s)),
|
|
|
|
num_pfx);
|
|
|
|
pkt = bpacket_queue_add(SUBGRP_PKTQ(subgrp), stream_dup(s),
|
2017-07-17 14:03:14 +02:00
|
|
|
NULL);
|
2015-05-20 03:03:47 +02:00
|
|
|
stream_reset(s);
|
|
|
|
return pkt;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
void subgroup_default_update_packet(struct update_subgroup *subgrp,
|
|
|
|
struct attr *attr, struct peer *from)
|
|
|
|
{
|
|
|
|
struct stream *s;
|
|
|
|
struct peer *peer;
|
|
|
|
struct prefix p;
|
|
|
|
unsigned long pos;
|
|
|
|
bgp_size_t total_attr_len;
|
|
|
|
afi_t afi;
|
|
|
|
safi_t safi;
|
|
|
|
struct bpacket_attr_vec_arr vecarr;
|
2022-01-27 08:51:59 +01:00
|
|
|
bool addpath_capable = false;
|
2023-08-11 09:49:14 +02:00
|
|
|
mpls_label_t label = MPLS_LABEL_IMPLICIT_NULL;
|
2024-02-26 18:11:09 +01:00
|
|
|
uint8_t num_labels = 0;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2015-05-20 03:03:47 +02:00
|
|
|
if (DISABLE_BGP_ANNOUNCE)
|
|
|
|
return;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2015-05-20 03:03:47 +02:00
|
|
|
if (!subgrp)
|
|
|
|
return;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2015-05-20 03:03:47 +02:00
|
|
|
peer = SUBGRP_PEER(subgrp);
|
|
|
|
afi = SUBGRP_AFI(subgrp);
|
|
|
|
safi = SUBGRP_SAFI(subgrp);
|
|
|
|
bpacket_attr_vec_arr_reset(&vecarr);
|
2022-01-27 08:51:59 +01:00
|
|
|
addpath_capable = bgp_addpath_encode_tx(peer, afi, safi);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
bgpd: Announce labeled-unicast default-originate
Without this patch, this just crashes:
```
(gdb) bt
0 raise (sig=sig@entry=11) at ../sysdeps/unix/sysv/linux/raise.c:51
1 0x00007f66d977b10c in core_handler (signo=11, siginfo=0x7ffd87aa0430, context=<optimized out>) at lib/sigevent.c:261
2 <signal handler called>
3 stream_put_labeled_prefix (s=s@entry=0x55bd3ce53050, p=p@entry=0x7ffd87aa0a20, label=label@entry=0x0, addpath_capable=<optimized out>, addpath_tx_id=addpath_tx_id@entry=1)
at lib/stream.c:1057
4 0x000055bd3bfba176 in bgp_packet_mpattr_prefix (s=s@entry=0x55bd3ce53050, afi=afi@entry=AFI_IP, safi=safi@entry=SAFI_LABELED_UNICAST, p=p@entry=0x7ffd87aa0a20, prd=prd@entry=0x0,
label=label@entry=0x0, num_labels=0, addpath_capable=true, addpath_tx_id=1, attr=0x7ffd87aa2c20) at bgpd/bgp_attr.c:3964
5 0x000055bd3bfba2b5 in bgp_packet_attribute (bgp=0x55bd3cd8e470, bgp@entry=0x0, peer=peer@entry=0x55bd3cf21fc0, s=s@entry=0x55bd3ce53050, attr=attr@entry=0x7ffd87aa2c20,
vecarr=vecarr@entry=0x7ffd87aa0a10, p=p@entry=0x7ffd87aa0a20, afi=AFI_IP, safi=SAFI_LABELED_UNICAST, from=0x7f66d9ba9010, prd=0x0, label=0x0, num_labels=0, addpath_capable=true,
addpath_tx_id=1, bpi=0x0) at bgpd/bgp_attr.c:4139
6 0x000055bd3c04d455 in subgroup_default_update_packet (subgrp=subgrp@entry=0x55bd3cd885b0, attr=attr@entry=0x7ffd87aa2c20, from=from@entry=0x7f66d9ba9010) at bgpd/bgp_updgrp_packet.c:1129
7 0x000055bd3c04a9a5 in subgroup_default_originate (subgrp=0x55bd3cd885b0, withdraw=withdraw@entry=0) at bgpd/bgp_updgrp_adv.c:972
8 0x000055bd3c022668 in bgp_default_originate (peer=peer@entry=0x7f66d574a010, afi=afi@entry=AFI_IP, safi=safi@entry=SAFI_LABELED_UNICAST, withdraw=withdraw@entry=0)
at bgpd/bgp_route.c:5037
9 0x000055bd3c0922e0 in peer_default_originate_set (peer=0x7f66d574a010, afi=afi@entry=AFI_IP, safi=safi@entry=SAFI_LABELED_UNICAST, rmap=rmap@entry=0x0, route_map=route_map@entry=0x0)
at bgpd/bgpd.c:5428
10 0x000055bd3c076c07 in peer_default_originate_set_vty (set=1, rmap=0x0, safi=SAFI_LABELED_UNICAST, afi=AFI_IP, peer_str=<optimized out>, vty=0x55bd3ce4c900) at bgpd/bgp_vty.c:6941
11 neighbor_default_originate (self=<optimized out>, vty=0x55bd3ce4c900, argc=<optimized out>, argv=<optimized out>) at bgpd/bgp_vty.c:6958
12 0x00007f66d9721dc0 in cmd_execute_command_real (vline=vline@entry=0x55bd3cd874d0, vty=vty@entry=0x55bd3ce4c900, cmd=cmd@entry=0x0, up_level=up_level@entry=0, filter=FILTER_RELAXED)
at lib/command.c:996
13 0x00007f66d9721f39 in cmd_execute_command (vline=vline@entry=0x55bd3cd874d0, vty=vty@entry=0x55bd3ce4c900, cmd=cmd@entry=0x0, vtysh=vtysh@entry=0) at lib/command.c:1055
14 0x00007f66d9722162 in cmd_execute (vty=vty@entry=0x55bd3ce4c900, cmd=cmd@entry=0x55bd3cd8a230 "neighbor 192.168.34.4 default-originate ", matched=matched@entry=0x0, vtysh=vtysh@entry=0)
at lib/command.c:1223
15 0x00007f66d9792337 in vty_command (vty=vty@entry=0x55bd3ce4c900, buf=<optimized out>) at lib/vty.c:486
16 0x00007f66d9792570 in vty_execute (vty=0x55bd3ce4c900) at lib/vty.c:1249
```
Signed-off-by: Donatas Abraitis <donatas@opensourcerouting.org>
2022-12-07 21:57:29 +01:00
|
|
|
if (safi == SAFI_LABELED_UNICAST) {
|
2023-08-11 09:49:14 +02:00
|
|
|
label = mpls_lse_encode((afi == AFI_IP)
|
|
|
|
? MPLS_LABEL_IPV4_EXPLICIT_NULL
|
|
|
|
: MPLS_LABEL_IPV6_EXPLICIT_NULL,
|
|
|
|
0, 0, 1);
|
|
|
|
bgp_set_valid_label(&label);
|
bgpd: Announce labeled-unicast default-originate
Without this patch, this just crashes:
```
(gdb) bt
0 raise (sig=sig@entry=11) at ../sysdeps/unix/sysv/linux/raise.c:51
1 0x00007f66d977b10c in core_handler (signo=11, siginfo=0x7ffd87aa0430, context=<optimized out>) at lib/sigevent.c:261
2 <signal handler called>
3 stream_put_labeled_prefix (s=s@entry=0x55bd3ce53050, p=p@entry=0x7ffd87aa0a20, label=label@entry=0x0, addpath_capable=<optimized out>, addpath_tx_id=addpath_tx_id@entry=1)
at lib/stream.c:1057
4 0x000055bd3bfba176 in bgp_packet_mpattr_prefix (s=s@entry=0x55bd3ce53050, afi=afi@entry=AFI_IP, safi=safi@entry=SAFI_LABELED_UNICAST, p=p@entry=0x7ffd87aa0a20, prd=prd@entry=0x0,
label=label@entry=0x0, num_labels=0, addpath_capable=true, addpath_tx_id=1, attr=0x7ffd87aa2c20) at bgpd/bgp_attr.c:3964
5 0x000055bd3bfba2b5 in bgp_packet_attribute (bgp=0x55bd3cd8e470, bgp@entry=0x0, peer=peer@entry=0x55bd3cf21fc0, s=s@entry=0x55bd3ce53050, attr=attr@entry=0x7ffd87aa2c20,
vecarr=vecarr@entry=0x7ffd87aa0a10, p=p@entry=0x7ffd87aa0a20, afi=AFI_IP, safi=SAFI_LABELED_UNICAST, from=0x7f66d9ba9010, prd=0x0, label=0x0, num_labels=0, addpath_capable=true,
addpath_tx_id=1, bpi=0x0) at bgpd/bgp_attr.c:4139
6 0x000055bd3c04d455 in subgroup_default_update_packet (subgrp=subgrp@entry=0x55bd3cd885b0, attr=attr@entry=0x7ffd87aa2c20, from=from@entry=0x7f66d9ba9010) at bgpd/bgp_updgrp_packet.c:1129
7 0x000055bd3c04a9a5 in subgroup_default_originate (subgrp=0x55bd3cd885b0, withdraw=withdraw@entry=0) at bgpd/bgp_updgrp_adv.c:972
8 0x000055bd3c022668 in bgp_default_originate (peer=peer@entry=0x7f66d574a010, afi=afi@entry=AFI_IP, safi=safi@entry=SAFI_LABELED_UNICAST, withdraw=withdraw@entry=0)
at bgpd/bgp_route.c:5037
9 0x000055bd3c0922e0 in peer_default_originate_set (peer=0x7f66d574a010, afi=afi@entry=AFI_IP, safi=safi@entry=SAFI_LABELED_UNICAST, rmap=rmap@entry=0x0, route_map=route_map@entry=0x0)
at bgpd/bgpd.c:5428
10 0x000055bd3c076c07 in peer_default_originate_set_vty (set=1, rmap=0x0, safi=SAFI_LABELED_UNICAST, afi=AFI_IP, peer_str=<optimized out>, vty=0x55bd3ce4c900) at bgpd/bgp_vty.c:6941
11 neighbor_default_originate (self=<optimized out>, vty=0x55bd3ce4c900, argc=<optimized out>, argv=<optimized out>) at bgpd/bgp_vty.c:6958
12 0x00007f66d9721dc0 in cmd_execute_command_real (vline=vline@entry=0x55bd3cd874d0, vty=vty@entry=0x55bd3ce4c900, cmd=cmd@entry=0x0, up_level=up_level@entry=0, filter=FILTER_RELAXED)
at lib/command.c:996
13 0x00007f66d9721f39 in cmd_execute_command (vline=vline@entry=0x55bd3cd874d0, vty=vty@entry=0x55bd3ce4c900, cmd=cmd@entry=0x0, vtysh=vtysh@entry=0) at lib/command.c:1055
14 0x00007f66d9722162 in cmd_execute (vty=vty@entry=0x55bd3ce4c900, cmd=cmd@entry=0x55bd3cd8a230 "neighbor 192.168.34.4 default-originate ", matched=matched@entry=0x0, vtysh=vtysh@entry=0)
at lib/command.c:1223
15 0x00007f66d9792337 in vty_command (vty=vty@entry=0x55bd3ce4c900, buf=<optimized out>) at lib/vty.c:486
16 0x00007f66d9792570 in vty_execute (vty=0x55bd3ce4c900) at lib/vty.c:1249
```
Signed-off-by: Donatas Abraitis <donatas@opensourcerouting.org>
2022-12-07 21:57:29 +01:00
|
|
|
num_labels = 1;
|
|
|
|
}
|
|
|
|
|
2017-10-23 23:19:26 +02:00
|
|
|
memset(&p, 0, sizeof(p));
|
|
|
|
p.family = afi2family(afi);
|
|
|
|
p.prefixlen = 0;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2015-05-20 03:03:47 +02:00
|
|
|
/* Logging the attribute. */
|
|
|
|
if (bgp_debug_update(NULL, &p, subgrp->update_group, 0)) {
|
|
|
|
char attrstr[BUFSIZ];
|
2017-06-02 22:53:37 +02:00
|
|
|
/* ' with addpath ID ' 17
|
|
|
|
* max strlen of uint32 + 10
|
|
|
|
* +/- (just in case) + 1
|
|
|
|
* null terminator + 1
|
|
|
|
* ============================ 29 */
|
BGP: support for addpath TX
Signed-off-by: Daniel Walton <dwalton@cumulusnetworks.com>
Reviewed-by: Donald Sharp <sharpd@cumulusnetworks.com>
Reviewed-by: Vivek Venkataraman <vivek@cumulusnetworks.com
Ticket: CM-8014
This implements addpath TX with the first feature to use it
being "neighbor x.x.x.x addpath-tx-all-paths".
One change to show output is 'show ip bgp x.x.x.x'. If no addpath-tx
features are configured for any peers then everything looks the same
as it is today in that "Advertised to" is at the top and refers to
which peers the bestpath was advertise to.
root@superm-redxp-05[quagga-stash5]# vtysh -c 'show ip bgp 1.1.1.1'
BGP routing table entry for 1.1.1.1/32
Paths: (6 available, best #6, table Default-IP-Routing-Table)
Advertised to non peer-group peers:
r1(10.0.0.1) r2(10.0.0.2) r3(10.0.0.3) r4(10.0.0.4) r5(10.0.0.5) r6(10.0.0.6) r8(10.0.0.8)
Local, (Received from a RR-client)
12.12.12.12 (metric 20) from r2(10.0.0.2) (10.0.0.2)
Origin IGP, metric 0, localpref 100, valid, internal
AddPath ID: RX 0, TX 8
Last update: Fri Oct 30 18:26:44 2015
[snip]
but once you enable an addpath feature we must display "Advertised to" on a path-by-path basis:
superm-redxp-05# show ip bgp 1.1.1.1/32
BGP routing table entry for 1.1.1.1/32
Paths: (6 available, best #6, table Default-IP-Routing-Table)
Local, (Received from a RR-client)
12.12.12.12 (metric 20) from r2(10.0.0.2) (10.0.0.2)
Origin IGP, metric 0, localpref 100, valid, internal
AddPath ID: RX 0, TX 8
Advertised to: r8(10.0.0.8)
Last update: Fri Oct 30 18:26:44 2015
Local, (Received from a RR-client)
34.34.34.34 (metric 20) from r3(10.0.0.3) (10.0.0.3)
Origin IGP, metric 0, localpref 100, valid, internal
AddPath ID: RX 0, TX 7
Advertised to: r8(10.0.0.8)
Last update: Fri Oct 30 18:26:39 2015
Local, (Received from a RR-client)
56.56.56.56 (metric 20) from r6(10.0.0.6) (10.0.0.6)
Origin IGP, metric 0, localpref 100, valid, internal
AddPath ID: RX 0, TX 6
Advertised to: r8(10.0.0.8)
Last update: Fri Oct 30 18:26:39 2015
Local, (Received from a RR-client)
56.56.56.56 (metric 20) from r5(10.0.0.5) (10.0.0.5)
Origin IGP, metric 0, localpref 100, valid, internal
AddPath ID: RX 0, TX 5
Advertised to: r8(10.0.0.8)
Last update: Fri Oct 30 18:26:39 2015
Local, (Received from a RR-client)
34.34.34.34 (metric 20) from r4(10.0.0.4) (10.0.0.4)
Origin IGP, metric 0, localpref 100, valid, internal
AddPath ID: RX 0, TX 4
Advertised to: r8(10.0.0.8)
Last update: Fri Oct 30 18:26:39 2015
Local, (Received from a RR-client)
12.12.12.12 (metric 20) from r1(10.0.0.1) (10.0.0.1)
Origin IGP, metric 0, localpref 100, valid, internal, best
AddPath ID: RX 0, TX 3
Advertised to: r1(10.0.0.1) r2(10.0.0.2) r3(10.0.0.3) r4(10.0.0.4) r5(10.0.0.5) r6(10.0.0.6) r8(10.0.0.8)
Last update: Fri Oct 30 18:26:34 2015
superm-redxp-05#
2015-11-05 18:29:43 +01:00
|
|
|
char tx_id_buf[30];
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2015-05-20 03:03:47 +02:00
|
|
|
attrstr[0] = '\0';
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2020-08-18 20:43:07 +02:00
|
|
|
bgp_dump_attr(attr, attrstr, sizeof(attrstr));
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2022-01-27 08:51:59 +01:00
|
|
|
if (addpath_capable)
|
2017-06-02 22:53:37 +02:00
|
|
|
snprintf(tx_id_buf, sizeof(tx_id_buf),
|
|
|
|
" with addpath ID %u",
|
|
|
|
BGP_ADDPATH_TX_ID_FOR_DEFAULT_ORIGINATE);
|
2018-10-23 22:13:46 +02:00
|
|
|
else
|
|
|
|
tx_id_buf[0] = '\0';
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2020-10-18 13:33:54 +02:00
|
|
|
zlog_debug("u%" PRIu64 ":s%" PRIu64 " send UPDATE %pFX%s %s",
|
|
|
|
(SUBGRP_UPDGRP(subgrp))->id, subgrp->id, &p,
|
|
|
|
tx_id_buf, attrstr);
|
2015-05-20 03:03:47 +02:00
|
|
|
}
|
|
|
|
|
2021-02-25 18:46:49 +01:00
|
|
|
s = stream_new(peer->max_packet_size);
|
2015-05-20 03:03:47 +02:00
|
|
|
|
|
|
|
/* Make BGP update packet. */
|
|
|
|
bgp_packet_set_marker(s, BGP_MSG_UPDATE);
|
|
|
|
|
|
|
|
/* Unfeasible Routes Length. */
|
|
|
|
stream_putw(s, 0);
|
|
|
|
|
|
|
|
/* Make place for total attribute length. */
|
|
|
|
pos = stream_get_endp(s);
|
|
|
|
stream_putw(s, 0);
|
2023-08-11 09:49:14 +02:00
|
|
|
total_attr_len =
|
|
|
|
bgp_packet_attribute(NULL, peer, s, attr, &vecarr, &p, afi,
|
|
|
|
safi, from, NULL, &label, num_labels,
|
|
|
|
addpath_capable,
|
|
|
|
BGP_ADDPATH_TX_ID_FOR_DEFAULT_ORIGINATE,
|
|
|
|
NULL);
|
2015-05-20 03:03:47 +02:00
|
|
|
|
|
|
|
/* Set Total Path Attribute Length. */
|
|
|
|
stream_putw_at(s, pos, total_attr_len);
|
|
|
|
|
|
|
|
/* NLRI set. */
|
2015-06-11 18:19:12 +02:00
|
|
|
if (p.family == AF_INET && safi == SAFI_UNICAST
|
2017-05-10 15:40:29 +02:00
|
|
|
&& !peer_cap_enhe(peer, afi, safi))
|
BGP: support for addpath TX
Signed-off-by: Daniel Walton <dwalton@cumulusnetworks.com>
Reviewed-by: Donald Sharp <sharpd@cumulusnetworks.com>
Reviewed-by: Vivek Venkataraman <vivek@cumulusnetworks.com
Ticket: CM-8014
This implements addpath TX with the first feature to use it
being "neighbor x.x.x.x addpath-tx-all-paths".
One change to show output is 'show ip bgp x.x.x.x'. If no addpath-tx
features are configured for any peers then everything looks the same
as it is today in that "Advertised to" is at the top and refers to
which peers the bestpath was advertise to.
root@superm-redxp-05[quagga-stash5]# vtysh -c 'show ip bgp 1.1.1.1'
BGP routing table entry for 1.1.1.1/32
Paths: (6 available, best #6, table Default-IP-Routing-Table)
Advertised to non peer-group peers:
r1(10.0.0.1) r2(10.0.0.2) r3(10.0.0.3) r4(10.0.0.4) r5(10.0.0.5) r6(10.0.0.6) r8(10.0.0.8)
Local, (Received from a RR-client)
12.12.12.12 (metric 20) from r2(10.0.0.2) (10.0.0.2)
Origin IGP, metric 0, localpref 100, valid, internal
AddPath ID: RX 0, TX 8
Last update: Fri Oct 30 18:26:44 2015
[snip]
but once you enable an addpath feature we must display "Advertised to" on a path-by-path basis:
superm-redxp-05# show ip bgp 1.1.1.1/32
BGP routing table entry for 1.1.1.1/32
Paths: (6 available, best #6, table Default-IP-Routing-Table)
Local, (Received from a RR-client)
12.12.12.12 (metric 20) from r2(10.0.0.2) (10.0.0.2)
Origin IGP, metric 0, localpref 100, valid, internal
AddPath ID: RX 0, TX 8
Advertised to: r8(10.0.0.8)
Last update: Fri Oct 30 18:26:44 2015
Local, (Received from a RR-client)
34.34.34.34 (metric 20) from r3(10.0.0.3) (10.0.0.3)
Origin IGP, metric 0, localpref 100, valid, internal
AddPath ID: RX 0, TX 7
Advertised to: r8(10.0.0.8)
Last update: Fri Oct 30 18:26:39 2015
Local, (Received from a RR-client)
56.56.56.56 (metric 20) from r6(10.0.0.6) (10.0.0.6)
Origin IGP, metric 0, localpref 100, valid, internal
AddPath ID: RX 0, TX 6
Advertised to: r8(10.0.0.8)
Last update: Fri Oct 30 18:26:39 2015
Local, (Received from a RR-client)
56.56.56.56 (metric 20) from r5(10.0.0.5) (10.0.0.5)
Origin IGP, metric 0, localpref 100, valid, internal
AddPath ID: RX 0, TX 5
Advertised to: r8(10.0.0.8)
Last update: Fri Oct 30 18:26:39 2015
Local, (Received from a RR-client)
34.34.34.34 (metric 20) from r4(10.0.0.4) (10.0.0.4)
Origin IGP, metric 0, localpref 100, valid, internal
AddPath ID: RX 0, TX 4
Advertised to: r8(10.0.0.8)
Last update: Fri Oct 30 18:26:39 2015
Local, (Received from a RR-client)
12.12.12.12 (metric 20) from r1(10.0.0.1) (10.0.0.1)
Origin IGP, metric 0, localpref 100, valid, internal, best
AddPath ID: RX 0, TX 3
Advertised to: r1(10.0.0.1) r2(10.0.0.2) r3(10.0.0.3) r4(10.0.0.4) r5(10.0.0.5) r6(10.0.0.6) r8(10.0.0.8)
Last update: Fri Oct 30 18:26:34 2015
superm-redxp-05#
2015-11-05 18:29:43 +01:00
|
|
|
stream_put_prefix_addpath(
|
2022-01-27 08:51:59 +01:00
|
|
|
s, &p, addpath_capable,
|
BGP: support for addpath TX
Signed-off-by: Daniel Walton <dwalton@cumulusnetworks.com>
Reviewed-by: Donald Sharp <sharpd@cumulusnetworks.com>
Reviewed-by: Vivek Venkataraman <vivek@cumulusnetworks.com
Ticket: CM-8014
This implements addpath TX with the first feature to use it
being "neighbor x.x.x.x addpath-tx-all-paths".
One change to show output is 'show ip bgp x.x.x.x'. If no addpath-tx
features are configured for any peers then everything looks the same
as it is today in that "Advertised to" is at the top and refers to
which peers the bestpath was advertise to.
root@superm-redxp-05[quagga-stash5]# vtysh -c 'show ip bgp 1.1.1.1'
BGP routing table entry for 1.1.1.1/32
Paths: (6 available, best #6, table Default-IP-Routing-Table)
Advertised to non peer-group peers:
r1(10.0.0.1) r2(10.0.0.2) r3(10.0.0.3) r4(10.0.0.4) r5(10.0.0.5) r6(10.0.0.6) r8(10.0.0.8)
Local, (Received from a RR-client)
12.12.12.12 (metric 20) from r2(10.0.0.2) (10.0.0.2)
Origin IGP, metric 0, localpref 100, valid, internal
AddPath ID: RX 0, TX 8
Last update: Fri Oct 30 18:26:44 2015
[snip]
but once you enable an addpath feature we must display "Advertised to" on a path-by-path basis:
superm-redxp-05# show ip bgp 1.1.1.1/32
BGP routing table entry for 1.1.1.1/32
Paths: (6 available, best #6, table Default-IP-Routing-Table)
Local, (Received from a RR-client)
12.12.12.12 (metric 20) from r2(10.0.0.2) (10.0.0.2)
Origin IGP, metric 0, localpref 100, valid, internal
AddPath ID: RX 0, TX 8
Advertised to: r8(10.0.0.8)
Last update: Fri Oct 30 18:26:44 2015
Local, (Received from a RR-client)
34.34.34.34 (metric 20) from r3(10.0.0.3) (10.0.0.3)
Origin IGP, metric 0, localpref 100, valid, internal
AddPath ID: RX 0, TX 7
Advertised to: r8(10.0.0.8)
Last update: Fri Oct 30 18:26:39 2015
Local, (Received from a RR-client)
56.56.56.56 (metric 20) from r6(10.0.0.6) (10.0.0.6)
Origin IGP, metric 0, localpref 100, valid, internal
AddPath ID: RX 0, TX 6
Advertised to: r8(10.0.0.8)
Last update: Fri Oct 30 18:26:39 2015
Local, (Received from a RR-client)
56.56.56.56 (metric 20) from r5(10.0.0.5) (10.0.0.5)
Origin IGP, metric 0, localpref 100, valid, internal
AddPath ID: RX 0, TX 5
Advertised to: r8(10.0.0.8)
Last update: Fri Oct 30 18:26:39 2015
Local, (Received from a RR-client)
34.34.34.34 (metric 20) from r4(10.0.0.4) (10.0.0.4)
Origin IGP, metric 0, localpref 100, valid, internal
AddPath ID: RX 0, TX 4
Advertised to: r8(10.0.0.8)
Last update: Fri Oct 30 18:26:39 2015
Local, (Received from a RR-client)
12.12.12.12 (metric 20) from r1(10.0.0.1) (10.0.0.1)
Origin IGP, metric 0, localpref 100, valid, internal, best
AddPath ID: RX 0, TX 3
Advertised to: r1(10.0.0.1) r2(10.0.0.2) r3(10.0.0.3) r4(10.0.0.4) r5(10.0.0.5) r6(10.0.0.6) r8(10.0.0.8)
Last update: Fri Oct 30 18:26:34 2015
superm-redxp-05#
2015-11-05 18:29:43 +01:00
|
|
|
BGP_ADDPATH_TX_ID_FOR_DEFAULT_ORIGINATE);
|
2015-05-20 03:03:47 +02:00
|
|
|
|
|
|
|
/* Set size. */
|
|
|
|
bgp_packet_set_size(s);
|
|
|
|
|
2015-08-18 14:41:58 +02:00
|
|
|
(void)bpacket_queue_add(SUBGRP_PKTQ(subgrp), s, &vecarr);
|
2017-06-12 22:20:50 +02:00
|
|
|
subgroup_trigger_write(subgrp);
|
2022-05-26 08:45:57 +02:00
|
|
|
|
|
|
|
if (!CHECK_FLAG(subgrp->sflags,
|
|
|
|
SUBGRP_STATUS_PEER_DEFAULT_ORIGINATED)) {
|
|
|
|
subgrp->scount++;
|
|
|
|
SET_FLAG(subgrp->sflags, SUBGRP_STATUS_PEER_DEFAULT_ORIGINATED);
|
|
|
|
}
|
2015-05-20 03:03:47 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void subgroup_default_withdraw_packet(struct update_subgroup *subgrp)
|
|
|
|
{
|
2015-06-11 18:19:12 +02:00
|
|
|
struct peer *peer;
|
2015-05-20 03:03:47 +02:00
|
|
|
struct stream *s;
|
|
|
|
struct prefix p;
|
|
|
|
unsigned long attrlen_pos = 0;
|
|
|
|
unsigned long cp;
|
|
|
|
bgp_size_t unfeasible_len;
|
2016-05-07 02:19:05 +02:00
|
|
|
bgp_size_t total_attr_len = 0;
|
2015-05-20 03:03:47 +02:00
|
|
|
size_t mp_start = 0;
|
|
|
|
size_t mplen_pos = 0;
|
|
|
|
afi_t afi;
|
|
|
|
safi_t safi;
|
2022-01-27 08:51:59 +01:00
|
|
|
bool addpath_capable = false;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2015-05-20 03:03:47 +02:00
|
|
|
if (DISABLE_BGP_ANNOUNCE)
|
|
|
|
return;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2015-06-11 18:19:12 +02:00
|
|
|
peer = SUBGRP_PEER(subgrp);
|
2015-05-20 03:03:47 +02:00
|
|
|
afi = SUBGRP_AFI(subgrp);
|
|
|
|
safi = SUBGRP_SAFI(subgrp);
|
2022-01-27 08:51:59 +01:00
|
|
|
addpath_capable = bgp_addpath_encode_tx(peer, afi, safi);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2017-10-23 23:19:26 +02:00
|
|
|
memset(&p, 0, sizeof(p));
|
|
|
|
p.family = afi2family(afi);
|
|
|
|
p.prefixlen = 0;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2015-05-20 03:03:47 +02:00
|
|
|
if (bgp_debug_update(NULL, &p, subgrp->update_group, 0)) {
|
2017-06-02 22:53:37 +02:00
|
|
|
/* ' with addpath ID ' 17
|
|
|
|
* max strlen of uint32 + 10
|
|
|
|
* +/- (just in case) + 1
|
|
|
|
* null terminator + 1
|
|
|
|
* ============================ 29 */
|
|
|
|
char tx_id_buf[30];
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2022-01-27 08:51:59 +01:00
|
|
|
if (addpath_capable)
|
2017-06-02 22:53:37 +02:00
|
|
|
snprintf(tx_id_buf, sizeof(tx_id_buf),
|
|
|
|
" with addpath ID %u",
|
|
|
|
BGP_ADDPATH_TX_ID_FOR_DEFAULT_ORIGINATE);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2020-10-18 13:33:54 +02:00
|
|
|
zlog_debug("u%" PRIu64 ":s%" PRIu64
|
|
|
|
" send UPDATE %pFX%s -- unreachable",
|
|
|
|
(SUBGRP_UPDGRP(subgrp))->id, subgrp->id, &p,
|
|
|
|
tx_id_buf);
|
2015-05-20 03:03:47 +02:00
|
|
|
}
|
|
|
|
|
2021-02-25 18:46:49 +01:00
|
|
|
s = stream_new(peer->max_packet_size);
|
2015-05-20 03:03:47 +02:00
|
|
|
|
|
|
|
/* Make BGP update packet. */
|
|
|
|
bgp_packet_set_marker(s, BGP_MSG_UPDATE);
|
|
|
|
|
|
|
|
/* Unfeasible Routes Length. */;
|
|
|
|
cp = stream_get_endp(s);
|
|
|
|
stream_putw(s, 0);
|
|
|
|
|
|
|
|
/* Withdrawn Routes. */
|
2015-06-11 18:19:12 +02:00
|
|
|
if (p.family == AF_INET && safi == SAFI_UNICAST
|
2017-05-10 15:40:29 +02:00
|
|
|
&& !peer_cap_enhe(peer, afi, safi)) {
|
BGP: support for addpath TX
Signed-off-by: Daniel Walton <dwalton@cumulusnetworks.com>
Reviewed-by: Donald Sharp <sharpd@cumulusnetworks.com>
Reviewed-by: Vivek Venkataraman <vivek@cumulusnetworks.com
Ticket: CM-8014
This implements addpath TX with the first feature to use it
being "neighbor x.x.x.x addpath-tx-all-paths".
One change to show output is 'show ip bgp x.x.x.x'. If no addpath-tx
features are configured for any peers then everything looks the same
as it is today in that "Advertised to" is at the top and refers to
which peers the bestpath was advertise to.
root@superm-redxp-05[quagga-stash5]# vtysh -c 'show ip bgp 1.1.1.1'
BGP routing table entry for 1.1.1.1/32
Paths: (6 available, best #6, table Default-IP-Routing-Table)
Advertised to non peer-group peers:
r1(10.0.0.1) r2(10.0.0.2) r3(10.0.0.3) r4(10.0.0.4) r5(10.0.0.5) r6(10.0.0.6) r8(10.0.0.8)
Local, (Received from a RR-client)
12.12.12.12 (metric 20) from r2(10.0.0.2) (10.0.0.2)
Origin IGP, metric 0, localpref 100, valid, internal
AddPath ID: RX 0, TX 8
Last update: Fri Oct 30 18:26:44 2015
[snip]
but once you enable an addpath feature we must display "Advertised to" on a path-by-path basis:
superm-redxp-05# show ip bgp 1.1.1.1/32
BGP routing table entry for 1.1.1.1/32
Paths: (6 available, best #6, table Default-IP-Routing-Table)
Local, (Received from a RR-client)
12.12.12.12 (metric 20) from r2(10.0.0.2) (10.0.0.2)
Origin IGP, metric 0, localpref 100, valid, internal
AddPath ID: RX 0, TX 8
Advertised to: r8(10.0.0.8)
Last update: Fri Oct 30 18:26:44 2015
Local, (Received from a RR-client)
34.34.34.34 (metric 20) from r3(10.0.0.3) (10.0.0.3)
Origin IGP, metric 0, localpref 100, valid, internal
AddPath ID: RX 0, TX 7
Advertised to: r8(10.0.0.8)
Last update: Fri Oct 30 18:26:39 2015
Local, (Received from a RR-client)
56.56.56.56 (metric 20) from r6(10.0.0.6) (10.0.0.6)
Origin IGP, metric 0, localpref 100, valid, internal
AddPath ID: RX 0, TX 6
Advertised to: r8(10.0.0.8)
Last update: Fri Oct 30 18:26:39 2015
Local, (Received from a RR-client)
56.56.56.56 (metric 20) from r5(10.0.0.5) (10.0.0.5)
Origin IGP, metric 0, localpref 100, valid, internal
AddPath ID: RX 0, TX 5
Advertised to: r8(10.0.0.8)
Last update: Fri Oct 30 18:26:39 2015
Local, (Received from a RR-client)
34.34.34.34 (metric 20) from r4(10.0.0.4) (10.0.0.4)
Origin IGP, metric 0, localpref 100, valid, internal
AddPath ID: RX 0, TX 4
Advertised to: r8(10.0.0.8)
Last update: Fri Oct 30 18:26:39 2015
Local, (Received from a RR-client)
12.12.12.12 (metric 20) from r1(10.0.0.1) (10.0.0.1)
Origin IGP, metric 0, localpref 100, valid, internal, best
AddPath ID: RX 0, TX 3
Advertised to: r1(10.0.0.1) r2(10.0.0.2) r3(10.0.0.3) r4(10.0.0.4) r5(10.0.0.5) r6(10.0.0.6) r8(10.0.0.8)
Last update: Fri Oct 30 18:26:34 2015
superm-redxp-05#
2015-11-05 18:29:43 +01:00
|
|
|
stream_put_prefix_addpath(
|
2022-01-27 08:51:59 +01:00
|
|
|
s, &p, addpath_capable,
|
BGP: support for addpath TX
Signed-off-by: Daniel Walton <dwalton@cumulusnetworks.com>
Reviewed-by: Donald Sharp <sharpd@cumulusnetworks.com>
Reviewed-by: Vivek Venkataraman <vivek@cumulusnetworks.com
Ticket: CM-8014
This implements addpath TX with the first feature to use it
being "neighbor x.x.x.x addpath-tx-all-paths".
One change to show output is 'show ip bgp x.x.x.x'. If no addpath-tx
features are configured for any peers then everything looks the same
as it is today in that "Advertised to" is at the top and refers to
which peers the bestpath was advertise to.
root@superm-redxp-05[quagga-stash5]# vtysh -c 'show ip bgp 1.1.1.1'
BGP routing table entry for 1.1.1.1/32
Paths: (6 available, best #6, table Default-IP-Routing-Table)
Advertised to non peer-group peers:
r1(10.0.0.1) r2(10.0.0.2) r3(10.0.0.3) r4(10.0.0.4) r5(10.0.0.5) r6(10.0.0.6) r8(10.0.0.8)
Local, (Received from a RR-client)
12.12.12.12 (metric 20) from r2(10.0.0.2) (10.0.0.2)
Origin IGP, metric 0, localpref 100, valid, internal
AddPath ID: RX 0, TX 8
Last update: Fri Oct 30 18:26:44 2015
[snip]
but once you enable an addpath feature we must display "Advertised to" on a path-by-path basis:
superm-redxp-05# show ip bgp 1.1.1.1/32
BGP routing table entry for 1.1.1.1/32
Paths: (6 available, best #6, table Default-IP-Routing-Table)
Local, (Received from a RR-client)
12.12.12.12 (metric 20) from r2(10.0.0.2) (10.0.0.2)
Origin IGP, metric 0, localpref 100, valid, internal
AddPath ID: RX 0, TX 8
Advertised to: r8(10.0.0.8)
Last update: Fri Oct 30 18:26:44 2015
Local, (Received from a RR-client)
34.34.34.34 (metric 20) from r3(10.0.0.3) (10.0.0.3)
Origin IGP, metric 0, localpref 100, valid, internal
AddPath ID: RX 0, TX 7
Advertised to: r8(10.0.0.8)
Last update: Fri Oct 30 18:26:39 2015
Local, (Received from a RR-client)
56.56.56.56 (metric 20) from r6(10.0.0.6) (10.0.0.6)
Origin IGP, metric 0, localpref 100, valid, internal
AddPath ID: RX 0, TX 6
Advertised to: r8(10.0.0.8)
Last update: Fri Oct 30 18:26:39 2015
Local, (Received from a RR-client)
56.56.56.56 (metric 20) from r5(10.0.0.5) (10.0.0.5)
Origin IGP, metric 0, localpref 100, valid, internal
AddPath ID: RX 0, TX 5
Advertised to: r8(10.0.0.8)
Last update: Fri Oct 30 18:26:39 2015
Local, (Received from a RR-client)
34.34.34.34 (metric 20) from r4(10.0.0.4) (10.0.0.4)
Origin IGP, metric 0, localpref 100, valid, internal
AddPath ID: RX 0, TX 4
Advertised to: r8(10.0.0.8)
Last update: Fri Oct 30 18:26:39 2015
Local, (Received from a RR-client)
12.12.12.12 (metric 20) from r1(10.0.0.1) (10.0.0.1)
Origin IGP, metric 0, localpref 100, valid, internal, best
AddPath ID: RX 0, TX 3
Advertised to: r1(10.0.0.1) r2(10.0.0.2) r3(10.0.0.3) r4(10.0.0.4) r5(10.0.0.5) r6(10.0.0.6) r8(10.0.0.8)
Last update: Fri Oct 30 18:26:34 2015
superm-redxp-05#
2015-11-05 18:29:43 +01:00
|
|
|
BGP_ADDPATH_TX_ID_FOR_DEFAULT_ORIGINATE);
|
2015-05-20 03:03:47 +02:00
|
|
|
|
|
|
|
unfeasible_len = stream_get_endp(s) - cp - 2;
|
|
|
|
|
|
|
|
/* Set unfeasible len. */
|
|
|
|
stream_putw_at(s, cp, unfeasible_len);
|
|
|
|
|
|
|
|
/* Set total path attribute length. */
|
|
|
|
stream_putw(s, 0);
|
|
|
|
} else {
|
|
|
|
attrlen_pos = stream_get_endp(s);
|
|
|
|
stream_putw(s, 0);
|
|
|
|
mp_start = stream_get_endp(s);
|
|
|
|
mplen_pos = bgp_packet_mpunreach_start(s, afi, safi);
|
BGP: support for addpath TX
Signed-off-by: Daniel Walton <dwalton@cumulusnetworks.com>
Reviewed-by: Donald Sharp <sharpd@cumulusnetworks.com>
Reviewed-by: Vivek Venkataraman <vivek@cumulusnetworks.com
Ticket: CM-8014
This implements addpath TX with the first feature to use it
being "neighbor x.x.x.x addpath-tx-all-paths".
One change to show output is 'show ip bgp x.x.x.x'. If no addpath-tx
features are configured for any peers then everything looks the same
as it is today in that "Advertised to" is at the top and refers to
which peers the bestpath was advertise to.
root@superm-redxp-05[quagga-stash5]# vtysh -c 'show ip bgp 1.1.1.1'
BGP routing table entry for 1.1.1.1/32
Paths: (6 available, best #6, table Default-IP-Routing-Table)
Advertised to non peer-group peers:
r1(10.0.0.1) r2(10.0.0.2) r3(10.0.0.3) r4(10.0.0.4) r5(10.0.0.5) r6(10.0.0.6) r8(10.0.0.8)
Local, (Received from a RR-client)
12.12.12.12 (metric 20) from r2(10.0.0.2) (10.0.0.2)
Origin IGP, metric 0, localpref 100, valid, internal
AddPath ID: RX 0, TX 8
Last update: Fri Oct 30 18:26:44 2015
[snip]
but once you enable an addpath feature we must display "Advertised to" on a path-by-path basis:
superm-redxp-05# show ip bgp 1.1.1.1/32
BGP routing table entry for 1.1.1.1/32
Paths: (6 available, best #6, table Default-IP-Routing-Table)
Local, (Received from a RR-client)
12.12.12.12 (metric 20) from r2(10.0.0.2) (10.0.0.2)
Origin IGP, metric 0, localpref 100, valid, internal
AddPath ID: RX 0, TX 8
Advertised to: r8(10.0.0.8)
Last update: Fri Oct 30 18:26:44 2015
Local, (Received from a RR-client)
34.34.34.34 (metric 20) from r3(10.0.0.3) (10.0.0.3)
Origin IGP, metric 0, localpref 100, valid, internal
AddPath ID: RX 0, TX 7
Advertised to: r8(10.0.0.8)
Last update: Fri Oct 30 18:26:39 2015
Local, (Received from a RR-client)
56.56.56.56 (metric 20) from r6(10.0.0.6) (10.0.0.6)
Origin IGP, metric 0, localpref 100, valid, internal
AddPath ID: RX 0, TX 6
Advertised to: r8(10.0.0.8)
Last update: Fri Oct 30 18:26:39 2015
Local, (Received from a RR-client)
56.56.56.56 (metric 20) from r5(10.0.0.5) (10.0.0.5)
Origin IGP, metric 0, localpref 100, valid, internal
AddPath ID: RX 0, TX 5
Advertised to: r8(10.0.0.8)
Last update: Fri Oct 30 18:26:39 2015
Local, (Received from a RR-client)
34.34.34.34 (metric 20) from r4(10.0.0.4) (10.0.0.4)
Origin IGP, metric 0, localpref 100, valid, internal
AddPath ID: RX 0, TX 4
Advertised to: r8(10.0.0.8)
Last update: Fri Oct 30 18:26:39 2015
Local, (Received from a RR-client)
12.12.12.12 (metric 20) from r1(10.0.0.1) (10.0.0.1)
Origin IGP, metric 0, localpref 100, valid, internal, best
AddPath ID: RX 0, TX 3
Advertised to: r1(10.0.0.1) r2(10.0.0.2) r3(10.0.0.3) r4(10.0.0.4) r5(10.0.0.5) r6(10.0.0.6) r8(10.0.0.8)
Last update: Fri Oct 30 18:26:34 2015
superm-redxp-05#
2015-11-05 18:29:43 +01:00
|
|
|
bgp_packet_mpunreach_prefix(
|
2022-01-27 08:51:59 +01:00
|
|
|
s, &p, afi, safi, NULL, NULL, 0, addpath_capable,
|
2016-09-05 14:19:40 +02:00
|
|
|
BGP_ADDPATH_TX_ID_FOR_DEFAULT_ORIGINATE, NULL);
|
2015-05-20 03:03:47 +02:00
|
|
|
|
|
|
|
/* Set the mp_unreach attr's length */
|
|
|
|
bgp_packet_mpunreach_end(s, mplen_pos);
|
|
|
|
|
|
|
|
/* Set total path attribute length. */
|
2015-08-18 14:41:58 +02:00
|
|
|
total_attr_len = stream_get_endp(s) - mp_start;
|
2015-05-20 03:03:47 +02:00
|
|
|
stream_putw_at(s, attrlen_pos, total_attr_len);
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
|
|
|
|
2015-08-18 14:41:58 +02:00
|
|
|
bgp_packet_set_size(s);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2015-08-18 14:41:58 +02:00
|
|
|
(void)bpacket_queue_add(SUBGRP_PKTQ(subgrp), s, NULL);
|
2017-06-12 22:20:50 +02:00
|
|
|
subgroup_trigger_write(subgrp);
|
2022-05-26 08:45:57 +02:00
|
|
|
|
|
|
|
if (CHECK_FLAG(subgrp->sflags, SUBGRP_STATUS_PEER_DEFAULT_ORIGINATED)) {
|
|
|
|
subgrp->scount--;
|
|
|
|
UNSET_FLAG(subgrp->sflags,
|
|
|
|
SUBGRP_STATUS_PEER_DEFAULT_ORIGINATED);
|
|
|
|
}
|
2015-05-20 03:03:47 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
bpacket_vec_arr_inherit_attr_flags(struct bpacket_attr_vec_arr *vecarr,
|
2022-04-12 10:42:27 +02:00
|
|
|
enum bpacket_attr_vec_type type,
|
2015-05-20 03:03:47 +02:00
|
|
|
struct attr *attr)
|
|
|
|
{
|
|
|
|
if (CHECK_FLAG(attr->rmap_change_flags,
|
2015-06-12 16:58:14 +02:00
|
|
|
BATTR_RMAP_NEXTHOP_PEER_ADDRESS))
|
|
|
|
SET_FLAG(vecarr->entries[BGP_ATTR_VEC_NH].flags,
|
|
|
|
BPKT_ATTRVEC_FLAGS_RMAP_NH_PEER_ADDRESS);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2015-06-12 16:58:14 +02:00
|
|
|
if (CHECK_FLAG(attr->rmap_change_flags, BATTR_REFLECTED))
|
|
|
|
SET_FLAG(vecarr->entries[BGP_ATTR_VEC_NH].flags,
|
|
|
|
BPKT_ATTRVEC_FLAGS_REFLECTED);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2015-06-12 16:58:14 +02:00
|
|
|
if (CHECK_FLAG(attr->rmap_change_flags, BATTR_RMAP_NEXTHOP_UNCHANGED))
|
2015-05-20 03:03:47 +02:00
|
|
|
SET_FLAG(vecarr->entries[BGP_ATTR_VEC_NH].flags,
|
2015-06-12 16:58:14 +02:00
|
|
|
BPKT_ATTRVEC_FLAGS_RMAP_NH_UNCHANGED);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2015-05-20 03:03:47 +02:00
|
|
|
if (CHECK_FLAG(attr->rmap_change_flags, BATTR_RMAP_IPV4_NHOP_CHANGED))
|
|
|
|
SET_FLAG(vecarr->entries[BGP_ATTR_VEC_NH].flags,
|
2015-06-12 16:58:14 +02:00
|
|
|
BPKT_ATTRVEC_FLAGS_RMAP_IPV4_NH_CHANGED);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2015-06-12 16:58:14 +02:00
|
|
|
if (CHECK_FLAG(attr->rmap_change_flags,
|
|
|
|
BATTR_RMAP_IPV6_GLOBAL_NHOP_CHANGED))
|
2015-05-20 03:03:47 +02:00
|
|
|
SET_FLAG(vecarr->entries[BGP_ATTR_VEC_NH].flags,
|
2015-06-12 16:58:14 +02:00
|
|
|
BPKT_ATTRVEC_FLAGS_RMAP_IPV6_GNH_CHANGED);
|
bgpd: Allow overriding MPLS VPN next-hops via route-maps
Just do not reset next-hop for MPLS VPN routes.
Example of 172.16.255.1/32 (using extended next-hop capability):
```
pe2# sh bgp ipv4 vpn
BGP table version is 4, local router ID is 10.10.10.20, vrf id 0
Default local pref 100, local AS 65001
Status codes: s suppressed, d damped, h history, * valid, > best, = multipath,
i internal, r RIB-failure, S Stale, R Removed
Nexthop codes: @NNN nexthop's vrf id, < announce-nh-self
Origin codes: i - IGP, e - EGP, ? - incomplete
RPKI validation codes: V valid, I invalid, N Not found
Network Next Hop Metric LocPrf Weight Path
Route Distinguisher: 192.168.1.2:2
*>i10.0.0.0/24 2001:db8:1::1 0 100 0 65000 ?
UN=2001:db8:1::1 EC{192.168.1.2:2} label=1111 type=bgp, subtype=0
*>i172.16.255.1/32 2001:db8::1 0 100 0 65000 ?
UN=2001:db8::1 EC{192.168.1.2:2} label=1111 type=bgp, subtype=0
*>i192.168.1.0/24 2001:db8:1::1 0 100 0 65000 ?
UN=2001:db8:1::1 EC{192.168.1.2:2} label=1111 type=bgp, subtype=0
*>i192.168.2.0/24 2001:db8:1::1 100 0 65000 ?
UN=2001:db8:1::1 EC{192.168.1.2:2} label=1111 type=bgp, subtype=0
Route Distinguisher: 192.168.2.2:2
*> 10.0.0.0/24 192.168.2.1@4< 0 50 0 65000 ?
UN=192.168.2.1 EC{192.168.2.2:2} label=2222 type=bgp, subtype=5
*> 172.16.255.1/32 192.168.2.1@4< 50 0 65000 ?
UN=192.168.2.1 EC{192.168.2.2:2} label=2222 type=bgp, subtype=5
*> 192.168.1.0/24 192.168.2.1@4< 50 0 65000 ?
UN=192.168.2.1 EC{192.168.2.2:2} label=2222 type=bgp, subtype=5
*> 192.168.2.0/24 192.168.2.1@4< 0 50 0 65000 ?
UN=192.168.2.1 EC{192.168.2.2:2} label=2222 type=bgp, subtype=5
Displayed 8 routes and 8 total paths
```
Signed-off-by: Donatas Abraitis <donatas@opensourcerouting.org>
2022-11-18 14:47:50 +01:00
|
|
|
|
|
|
|
if (CHECK_FLAG(attr->rmap_change_flags, BATTR_RMAP_VPNV4_NHOP_CHANGED))
|
|
|
|
SET_FLAG(vecarr->entries[BGP_ATTR_VEC_NH].flags,
|
|
|
|
BPKT_ATTRVEC_FLAGS_RMAP_VPNV4_NH_CHANGED);
|
|
|
|
|
|
|
|
if (CHECK_FLAG(attr->rmap_change_flags,
|
|
|
|
BATTR_RMAP_VPNV6_GLOBAL_NHOP_CHANGED))
|
|
|
|
SET_FLAG(vecarr->entries[BGP_ATTR_VEC_NH].flags,
|
|
|
|
BPKT_ATTRVEC_FLAGS_RMAP_VPNV6_GNH_CHANGED);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2015-05-20 03:03:49 +02:00
|
|
|
if (CHECK_FLAG(attr->rmap_change_flags,
|
2015-06-12 16:58:14 +02:00
|
|
|
BATTR_RMAP_IPV6_LL_NHOP_CHANGED))
|
2015-05-20 03:03:49 +02:00
|
|
|
SET_FLAG(vecarr->entries[BGP_ATTR_VEC_NH].flags,
|
2015-06-12 16:58:14 +02:00
|
|
|
BPKT_ATTRVEC_FLAGS_RMAP_IPV6_LNH_CHANGED);
|
2015-05-20 03:03:47 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Reset the Attributes vector array. The vector array is used to override
|
|
|
|
* certain output parameters in the packet for a particular peer
|
|
|
|
*/
|
|
|
|
void bpacket_attr_vec_arr_reset(struct bpacket_attr_vec_arr *vecarr)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
|
|
|
if (!vecarr)
|
|
|
|
return;
|
|
|
|
|
|
|
|
i = 0;
|
|
|
|
while (i < BGP_ATTR_VEC_MAX) {
|
|
|
|
vecarr->entries[i].flags = 0;
|
|
|
|
vecarr->entries[i].offset = 0;
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Setup a particular node entry in the vecarr */
|
|
|
|
void bpacket_attr_vec_arr_set_vec(struct bpacket_attr_vec_arr *vecarr,
|
2022-04-12 10:42:27 +02:00
|
|
|
enum bpacket_attr_vec_type type,
|
|
|
|
struct stream *s, struct attr *attr)
|
2015-05-20 03:03:47 +02:00
|
|
|
{
|
|
|
|
if (!vecarr)
|
|
|
|
return;
|
|
|
|
assert(type < BGP_ATTR_VEC_MAX);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2015-06-12 16:58:14 +02:00
|
|
|
SET_FLAG(vecarr->entries[type].flags, BPKT_ATTRVEC_FLAGS_UPDATED);
|
2015-05-20 03:03:47 +02:00
|
|
|
vecarr->entries[type].offset = stream_get_endp(s);
|
|
|
|
if (attr)
|
|
|
|
bpacket_vec_arr_inherit_attr_flags(vecarr, type, attr);
|
|
|
|
}
|