bgpd: Fixes and updates for VPNv6

VPNv6 changes picked from upstream needed fixes and updates due to some
fundamental changes implemented by Cumulus (BGP update-groups, RFC 5549
and nexthop setting etc.) which aren't present upstream.

Signed-off-by: Vivek Venkatraman <vivek@cumulusnetworks.com>
Updates: 945c8fe, 8ecd326, bb86c60, 93b73df, f4c8985
This commit is contained in:
vivek 2016-06-11 11:36:42 -07:00
parent d4fbc1de63
commit 6407da5a24
8 changed files with 24 additions and 80 deletions

View File

@ -41,7 +41,7 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
#include "bgpd/bgp_packet.h"
#include "bgpd/bgp_ecommunity.h"
#include "bgpd/bgp_updgrp.h"
#include "bgp_encap_types.h"
#include "bgpd/bgp_encap_types.h"
/* Attribute strings for logging. */
static const struct message attr_str [] =
@ -2457,6 +2457,7 @@ bgp_packet_mpattr_start (struct stream *s, afi_t afi, safi_t safi, afi_t nh_afi,
case AFI_IP:
switch (safi)
{
case SAFI_UNICAST:
case SAFI_MULTICAST:
bpacket_attr_vec_arr_set_vec (vecarr, BGP_ATTR_VEC_NH, s, attr);
stream_putc (s, 4);
@ -2469,7 +2470,6 @@ bgp_packet_mpattr_start (struct stream *s, afi_t afi, safi_t safi, afi_t nh_afi,
stream_putl (s, 0);
stream_put (s, &attr->extra->mp_nexthop_global_in, 4);
break;
case SAFI_UNICAST: /* invalid for IPv4 */
default:
break;
}
@ -2496,19 +2496,19 @@ bgp_packet_mpattr_start (struct stream *s, afi_t afi, safi_t safi, afi_t nh_afi,
struct attr_extra *attre = attr->extra;
assert (attr->extra);
if (attre->mp_nexthop_len == 16) {
if (attre->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL) {
stream_putc (s, 24);
stream_putl (s, 0); /* RD = 0, per RFC */
stream_putl (s, 0);
stream_put (s, &attre->mp_nexthop_global, 16);
} else if (attre->mp_nexthop_len == 32) {
stream_put (s, &attre->mp_nexthop_global, IPV6_MAX_BYTELEN);
} else if (attre->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL) {
stream_putc (s, 48);
stream_putl (s, 0); /* RD = 0, per RFC */
stream_putl (s, 0);
stream_put (s, &attre->mp_nexthop_global, 16);
stream_put (s, &attre->mp_nexthop_global, IPV6_MAX_BYTELEN);
stream_putl (s, 0); /* RD = 0, per RFC */
stream_putl (s, 0);
stream_put (s, &attre->mp_nexthop_local, 16);
stream_put (s, &attre->mp_nexthop_local, IPV6_MAX_BYTELEN);
}
}
break;

View File

@ -1167,7 +1167,8 @@ bgp_open_receive (struct peer *peer, bgp_size_t size)
}
}
if (peer->afc_nego[AFI_IP6][SAFI_UNICAST] ||
peer->afc_nego[AFI_IP6][SAFI_MULTICAST])
peer->afc_nego[AFI_IP6][SAFI_MULTICAST] ||
peer->afc_nego[AFI_IP6][SAFI_MPLS_VPN])
{
if (IN6_IS_ADDR_UNSPECIFIED (&peer->nexthop.v6_global))
{

View File

@ -2997,56 +2997,6 @@ bgp_clear_route_all (struct peer *peer)
bgp_clear_route (peer, afi, safi);
}
/*
* Finish freeing things when exiting
*/
static void
bgp_drain_workqueue_immediate (struct work_queue *wq)
{
if (!wq)
return;
if (!wq->thread)
{
/*
* no thread implies no queued items
*/
assert(!wq->items->count);
return;
}
while (wq->items->count)
{
if (wq->thread)
thread_cancel(wq->thread);
work_queue_run(wq->thread);
}
}
/*
* Special function to process clear node queue when bgpd is exiting
* and the thread scheduler is no longer running.
*/
void
bgp_peer_clear_node_queue_drain_immediate(struct peer *peer)
{
if (!peer)
return;
bgp_drain_workqueue_immediate(peer->clear_node_queue);
}
/*
* The work queues are not specific to a BGP instance, but the
* items in them refer to BGP instances, so this should be called
* before each BGP instance is deleted.
*/
void
bgp_process_queues_drain_immediate(void)
{
bgp_drain_workqueue_immediate(bm->process_main_queue);
}
void
bgp_clear_adj_in (struct peer *peer, afi_t afi, safi_t safi)
{

View File

@ -676,18 +676,10 @@ subgroup_update_packet (struct update_subgroup *subgrp)
/* If packet is empty, set attribute. */
if (stream_empty (s))
{
struct prefix_rd *prd = NULL;
u_char *tag = NULL;
struct peer *from = NULL;
if (rn->prn)
prd = (struct prefix_rd *) &rn->prn->p;
if (binfo)
{
from = binfo->peer;
if (binfo->extra)
tag = binfo->extra->tag;
}
from = binfo->peer;
/* 1: Write the BGP message header - 16 bytes marker, 2 bytes length,
* one byte message type.
@ -710,12 +702,13 @@ subgroup_update_packet (struct update_subgroup *subgrp)
/* 5: Encode all the attributes, except MP_REACH_NLRI attr. */
total_attr_len = bgp_packet_attribute (NULL, peer, s,
adv->baa->attr, &vecarr,
&rn->p, afi, safi,
from, prd, tag, 0, 0);
NULL, afi, safi,
from, NULL, NULL, 0, 0);
space_remaining = STREAM_CONCAT_REMAIN (s, snlri, STREAM_SIZE(s)) -
BGP_MAX_PACKET_SIZE_OVERFLOW;
space_needed = BGP_NLRI_LENGTH + PSIZE (rn->p.prefixlen);
space_needed = BGP_NLRI_LENGTH +
bgp_packet_mpattr_prefix_size (afi, safi, &rn->p);
/* If the attributes alone do not leave any room for NLRI then
* return */
@ -879,8 +872,8 @@ subgroup_withdraw_packet (struct update_subgroup *subgrp)
space_remaining = STREAM_REMAIN (s) -
BGP_MAX_PACKET_SIZE_OVERFLOW;
space_needed = (BGP_NLRI_LENGTH + BGP_TOTAL_ATTR_LEN +
PSIZE (rn->p.prefixlen));
space_needed = BGP_NLRI_LENGTH + BGP_TOTAL_ATTR_LEN +
bgp_packet_mpattr_prefix_size (afi, safi, &rn->p);
if (space_remaining < space_needed)
break;

View File

@ -74,9 +74,7 @@ bgp_node_afi (struct vty *vty)
safi_t
bgp_node_safi (struct vty *vty)
{
if (vty->node == BGP_VPNV4_NODE)
return SAFI_MPLS_VPN;
if (vty->node == BGP_VPNV6_NODE)
if (vty->node == BGP_VPNV4_NODE || vty->node == BGP_VPNV6_NODE)
return SAFI_MPLS_VPN;
if (vty->node == BGP_IPV4M_NODE || vty->node == BGP_IPV6M_NODE)
return SAFI_MULTICAST;

View File

@ -3044,8 +3044,6 @@ bgp_delete (struct bgp *bgp)
afi_t afi;
int i;
SET_FLAG(bgp->flags, BGP_FLAG_DELETING);
THREAD_OFF (bgp->t_startup);
if (BGP_DEBUG (zebra, ZEBRA))

View File

@ -68,6 +68,7 @@ enum bgp_af_index
BGP_AF_IPV4_VPN,
BGP_AF_IPV6_UNICAST,
BGP_AF_IPV6_MULTICAST,
BGP_AF_IPV6_VPN,
BGP_AF_MAX
};
@ -281,7 +282,6 @@ struct bgp
#define BGP_FLAG_MULTIPATH_RELAX_AS_SET (1 << 17)
#define BGP_FLAG_FORCE_STATIC_PROCESS (1 << 18)
#define BGP_FLAG_SHOW_HOSTNAME (1 << 19)
#define BGP_FLAG_DELETING (1 << 20)
/* BGP Per AF flags */
u_int16_t af_flags[AFI_MAX][SAFI_MAX];
@ -1362,6 +1362,9 @@ afindex (afi_t afi, safi_t safi)
case SAFI_MULTICAST:
return BGP_AF_IPV6_MULTICAST;
break;
case SAFI_MPLS_VPN:
return BGP_AF_IPV6_VPN;
break;
default:
return BGP_AF_MAX;
break;
@ -1403,7 +1406,8 @@ peer_group_af_configured (struct peer_group *group)
|| peer->afc[AFI_IP][SAFI_MULTICAST]
|| peer->afc[AFI_IP][SAFI_MPLS_VPN]
|| peer->afc[AFI_IP6][SAFI_UNICAST]
|| peer->afc[AFI_IP6][SAFI_MULTICAST])
|| peer->afc[AFI_IP6][SAFI_MULTICAST]
|| peer->afc[AFI_IP6][SAFI_MPLS_VPN])
return 1;
return 0;
}

View File

@ -575,7 +575,7 @@ vtysh_mark_file (const char *filename)
{
if ((prev_node == BGP_VPNV4_NODE || prev_node == BGP_IPV4_NODE
|| prev_node == BGP_IPV6_NODE || prev_node == BGP_IPV4M_NODE
|| prev_node == BGP_IPV6M_NODE)
|| prev_node == BGP_IPV6M_NODE || prev_node == BGP_VPNV6_NODE)
&& (tried == 1))
{
fprintf(stdout, "exit-address-family\n");