mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-08 14:04:32 +00:00
commit
4e33d4ef9b
@ -2742,6 +2742,7 @@ bgp_packet_mpattr_start (struct stream *s, afi_t afi, safi_t safi, afi_t nh_afi,
|
|||||||
else if (nh_afi == AFI_MAX)
|
else if (nh_afi == AFI_MAX)
|
||||||
nh_afi = BGP_NEXTHOP_AFI_FROM_NHLEN(attr->extra->mp_nexthop_len);
|
nh_afi = BGP_NEXTHOP_AFI_FROM_NHLEN(attr->extra->mp_nexthop_len);
|
||||||
/* Nexthop */
|
/* Nexthop */
|
||||||
|
bpacket_attr_vec_arr_set_vec (vecarr, BGP_ATTR_VEC_NH, s, attr);
|
||||||
switch (nh_afi)
|
switch (nh_afi)
|
||||||
{
|
{
|
||||||
case AFI_IP:
|
case AFI_IP:
|
||||||
@ -2754,7 +2755,6 @@ bgp_packet_mpattr_start (struct stream *s, afi_t afi, safi_t safi, afi_t nh_afi,
|
|||||||
stream_put_ipv4 (s, attr->nexthop.s_addr);
|
stream_put_ipv4 (s, attr->nexthop.s_addr);
|
||||||
break;
|
break;
|
||||||
case SAFI_MPLS_VPN:
|
case SAFI_MPLS_VPN:
|
||||||
bpacket_attr_vec_arr_set_vec (vecarr, BGP_ATTR_VEC_NH, s, attr);
|
|
||||||
stream_putc (s, 12);
|
stream_putc (s, 12);
|
||||||
stream_putl (s, 0); /* RD = 0, per RFC */
|
stream_putl (s, 0); /* RD = 0, per RFC */
|
||||||
stream_putl (s, 0);
|
stream_putl (s, 0);
|
||||||
@ -2777,7 +2777,6 @@ bgp_packet_mpattr_start (struct stream *s, afi_t afi, safi_t safi, afi_t nh_afi,
|
|||||||
struct attr_extra *attre = attr->extra;
|
struct attr_extra *attre = attr->extra;
|
||||||
|
|
||||||
assert (attr->extra);
|
assert (attr->extra);
|
||||||
bpacket_attr_vec_arr_set_vec (vecarr, BGP_ATTR_VEC_NH, s, attr);
|
|
||||||
stream_putc (s, attre->mp_nexthop_len);
|
stream_putc (s, attre->mp_nexthop_len);
|
||||||
stream_put (s, &attre->mp_nexthop_global, IPV6_MAX_BYTELEN);
|
stream_put (s, &attre->mp_nexthop_global, IPV6_MAX_BYTELEN);
|
||||||
if (attre->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL)
|
if (attre->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL)
|
||||||
|
@ -238,6 +238,42 @@ DEFUN (no_encap_network,
|
|||||||
0, NULL, NULL, NULL);
|
0, NULL, NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DEFUN (encapv6_network,
|
||||||
|
encapv6_network_cmd,
|
||||||
|
"network X:X::X:X/M rd ASN:nn_or_IP-address:nn [route-map WORD]",
|
||||||
|
"Specify a network to announce via BGP\n"
|
||||||
|
"IPv6 prefix <network>/<length>, e.g., 3ffe::/16\n"
|
||||||
|
"Specify Route Distinguisher\n"
|
||||||
|
"VPN Route Distinguisher\n"
|
||||||
|
"route map\n"
|
||||||
|
"route map name\n")
|
||||||
|
{
|
||||||
|
int idx_ipv6 = 1;
|
||||||
|
int idx_rd = 3;
|
||||||
|
int idx_rmap = 5;
|
||||||
|
const char *rmap_str = (argc == 6) ? argv[idx_rmap]->arg : NULL;
|
||||||
|
return bgp_static_set_safi (AFI_IP6, SAFI_ENCAP, vty, argv[idx_ipv6]->arg,
|
||||||
|
argv[idx_rd]->arg, NULL, rmap_str, 0, NULL,
|
||||||
|
NULL, NULL, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
DEFUN (no_encapv6_network,
|
||||||
|
no_encapv6_network_cmd,
|
||||||
|
"no network X:X::X:X/M rd ASN:nn_or_IP-address:nn [route-map WORD]",
|
||||||
|
NO_STR
|
||||||
|
"Specify a network to announce via BGP\n"
|
||||||
|
"IPv6 prefix <network>/<length>, e.g., 3ffe::/16\n"
|
||||||
|
"Specify Route Distinguisher\n"
|
||||||
|
"VPN Route Distinguisher\n"
|
||||||
|
"route map\n"
|
||||||
|
"route map name\n")
|
||||||
|
{
|
||||||
|
int idx_ipv6 = 2;
|
||||||
|
int idx_rd = 4;
|
||||||
|
return bgp_static_unset_safi (AFI_IP6, SAFI_ENCAP, vty, argv[idx_ipv6]->arg,
|
||||||
|
argv[idx_rd]->arg, NULL, 0, NULL, NULL, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
show_adj_route_encap (struct vty *vty, struct peer *peer, struct prefix_rd *prd)
|
show_adj_route_encap (struct vty *vty, struct peer *peer, struct prefix_rd *prd)
|
||||||
{
|
{
|
||||||
@ -758,6 +794,8 @@ bgp_encap_init (void)
|
|||||||
{
|
{
|
||||||
install_element (BGP_ENCAP_NODE, &encap_network_cmd);
|
install_element (BGP_ENCAP_NODE, &encap_network_cmd);
|
||||||
install_element (BGP_ENCAP_NODE, &no_encap_network_cmd);
|
install_element (BGP_ENCAP_NODE, &no_encap_network_cmd);
|
||||||
|
install_element (BGP_ENCAPV6_NODE, &encapv6_network_cmd);
|
||||||
|
install_element (BGP_ENCAPV6_NODE, &no_encapv6_network_cmd);
|
||||||
|
|
||||||
install_element (VIEW_NODE, &show_bgp_ipv4_encap_rd_cmd);
|
install_element (VIEW_NODE, &show_bgp_ipv4_encap_rd_cmd);
|
||||||
install_element (VIEW_NODE, &show_bgp_ipv4_encap_tags_cmd);
|
install_element (VIEW_NODE, &show_bgp_ipv4_encap_tags_cmd);
|
||||||
|
@ -381,31 +381,6 @@ out:
|
|||||||
return lret;
|
return lret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
|
||||||
str2tag (const char *str, u_char *tag)
|
|
||||||
{
|
|
||||||
unsigned long l;
|
|
||||||
char *endptr;
|
|
||||||
u_int32_t t;
|
|
||||||
|
|
||||||
if (*str == '-')
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
errno = 0;
|
|
||||||
l = strtoul (str, &endptr, 10);
|
|
||||||
|
|
||||||
if (*endptr != '\0' || errno || l > UINT32_MAX)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
t = (u_int32_t) l;
|
|
||||||
|
|
||||||
tag[0] = (u_char)(t >> 12);
|
|
||||||
tag[1] = (u_char)(t >> 4);
|
|
||||||
tag[2] = (u_char)(t << 4);
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
char *
|
char *
|
||||||
prefix_rd2str (struct prefix_rd *prd, char *buf, size_t size)
|
prefix_rd2str (struct prefix_rd *prd, char *buf, size_t size)
|
||||||
{
|
{
|
||||||
|
@ -104,7 +104,6 @@ extern void
|
|||||||
decode_rd_vnc_eth (u_char *pnt, struct rd_vnc_eth *rd_vnc_eth);
|
decode_rd_vnc_eth (u_char *pnt, struct rd_vnc_eth *rd_vnc_eth);
|
||||||
#endif
|
#endif
|
||||||
extern int str2prefix_rd (const char *, struct prefix_rd *);
|
extern int str2prefix_rd (const char *, struct prefix_rd *);
|
||||||
extern int str2tag (const char *, u_char *);
|
|
||||||
extern char *prefix_rd2str (struct prefix_rd *, char *, size_t);
|
extern char *prefix_rd2str (struct prefix_rd *, char *, size_t);
|
||||||
|
|
||||||
extern int
|
extern int
|
||||||
|
@ -10434,10 +10434,12 @@ bgp_config_write_network_vpn (struct vty *vty, struct bgp *bgp,
|
|||||||
prefix_rd2str (prd, rdbuf, RD_ADDRSTRLEN);
|
prefix_rd2str (prd, rdbuf, RD_ADDRSTRLEN);
|
||||||
label = decode_label (bgp_static->tag);
|
label = decode_label (bgp_static->tag);
|
||||||
|
|
||||||
vty_out (vty, " network %s/%d rd %s label %d",
|
vty_out (vty, " network %s/%d rd %s",
|
||||||
inet_ntop (p->family, &p->u.prefix, buf, SU_ADDRSTRLEN),
|
inet_ntop (p->family, &p->u.prefix, buf, SU_ADDRSTRLEN),
|
||||||
p->prefixlen,
|
p->prefixlen, rdbuf);
|
||||||
rdbuf, label);
|
if (safi == SAFI_MPLS_VPN)
|
||||||
|
vty_out (vty, " label %u", label);
|
||||||
|
|
||||||
if (bgp_static->rmap.name)
|
if (bgp_static->rmap.name)
|
||||||
vty_out (vty, " route-map %s", bgp_static->rmap.name);
|
vty_out (vty, " route-map %s", bgp_static->rmap.name);
|
||||||
else
|
else
|
||||||
|
@ -427,21 +427,33 @@ bpacket_reformat_for_peer (struct bpacket *pkt, struct peer_af *paf)
|
|||||||
nhafi = BGP_NEXTHOP_AFI_FROM_NHLEN(nhlen);
|
nhafi = BGP_NEXTHOP_AFI_FROM_NHLEN(nhlen);
|
||||||
if (peer_cap_enhe(peer))
|
if (peer_cap_enhe(peer))
|
||||||
nhafi = AFI_IP6;
|
nhafi = AFI_IP6;
|
||||||
if (paf->safi == SAFI_MPLS_VPN && /* if VPN && not global */
|
|
||||||
nhlen != BGP_ATTR_NHLEN_VPNV6_GLOBAL_AND_LL)
|
|
||||||
nhafi = AFI_MAX; /* no change allowed */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nhafi == AFI_IP)
|
if (nhafi == AFI_IP)
|
||||||
{
|
{
|
||||||
struct in_addr v4nh, *mod_v4nh;
|
struct in_addr v4nh, *mod_v4nh;
|
||||||
int nh_modified = 0;
|
int nh_modified = 0;
|
||||||
|
size_t offset_nh = vec->offset + 1;
|
||||||
|
|
||||||
route_map_sets_nh =
|
route_map_sets_nh =
|
||||||
(CHECK_FLAG (vec->flags, BPKT_ATTRVEC_FLAGS_RMAP_IPV4_NH_CHANGED) ||
|
(CHECK_FLAG (vec->flags, BPKT_ATTRVEC_FLAGS_RMAP_IPV4_NH_CHANGED) ||
|
||||||
CHECK_FLAG (vec->flags, BPKT_ATTRVEC_FLAGS_RMAP_NH_PEER_ADDRESS));
|
CHECK_FLAG (vec->flags, BPKT_ATTRVEC_FLAGS_RMAP_NH_PEER_ADDRESS));
|
||||||
|
|
||||||
stream_get_from (&v4nh, s, vec->offset + 1, 4);
|
switch (nhlen)
|
||||||
|
{
|
||||||
|
case BGP_ATTR_NHLEN_IPV4:
|
||||||
|
break;
|
||||||
|
case BGP_ATTR_NHLEN_VPNV4:
|
||||||
|
offset_nh += 8;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
/* TODO: handle IPv6 nexthops */
|
||||||
|
zlog_warn ("%s: %s: invalid MP nexthop length (AFI IP): %u",
|
||||||
|
__func__, peer->host, nhlen);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
stream_get_from (&v4nh, s, offset_nh, IPV4_MAX_BYTELEN);
|
||||||
mod_v4nh = &v4nh;
|
mod_v4nh = &v4nh;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -482,7 +494,7 @@ bpacket_reformat_for_peer (struct bpacket *pkt, struct peer_af *paf)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (nh_modified) /* allow for VPN RD */
|
if (nh_modified) /* allow for VPN RD */
|
||||||
stream_put_in_addr_at (s, vec->offset + 1 + nhlen - 4, mod_v4nh);
|
stream_put_in_addr_at (s, offset_nh, mod_v4nh);
|
||||||
|
|
||||||
if (bgp_debug_update(peer, NULL, NULL, 0))
|
if (bgp_debug_update(peer, NULL, NULL, 0))
|
||||||
zlog_debug ("u%" PRIu64 ":s%" PRIu64 " %s send UPDATE w/ nexthop %s%s",
|
zlog_debug ("u%" PRIu64 ":s%" PRIu64 " %s send UPDATE w/ nexthop %s%s",
|
||||||
@ -495,6 +507,8 @@ bpacket_reformat_for_peer (struct bpacket *pkt, struct peer_af *paf)
|
|||||||
struct in6_addr v6nhglobal, *mod_v6nhg;
|
struct in6_addr v6nhglobal, *mod_v6nhg;
|
||||||
struct in6_addr v6nhlocal, *mod_v6nhl;
|
struct in6_addr v6nhlocal, *mod_v6nhl;
|
||||||
int gnh_modified, lnh_modified;
|
int gnh_modified, lnh_modified;
|
||||||
|
size_t offset_nhglobal = vec->offset + 1;
|
||||||
|
size_t offset_nhlocal = vec->offset + 1;
|
||||||
|
|
||||||
gnh_modified = lnh_modified = 0;
|
gnh_modified = lnh_modified = 0;
|
||||||
mod_v6nhg = &v6nhglobal;
|
mod_v6nhg = &v6nhglobal;
|
||||||
@ -509,7 +523,28 @@ bpacket_reformat_for_peer (struct bpacket *pkt, struct peer_af *paf)
|
|||||||
* additional work being to handle 1 or 2 nexthops. Also, 3rd
|
* additional work being to handle 1 or 2 nexthops. Also, 3rd
|
||||||
* party nexthop is not propagated for EBGP right now.
|
* party nexthop is not propagated for EBGP right now.
|
||||||
*/
|
*/
|
||||||
stream_get_from (&v6nhglobal, s, vec->offset + 1, 16);
|
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 */
|
||||||
|
zlog_warn ("%s: %s: invalid MP nexthop length (AFI IP6): %u",
|
||||||
|
__func__, peer->host, nhlen);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
stream_get_from (&v6nhglobal, s, offset_nhglobal, IPV6_MAX_BYTELEN);
|
||||||
if (route_map_sets_nh)
|
if (route_map_sets_nh)
|
||||||
{
|
{
|
||||||
if (CHECK_FLAG(vec->flags,
|
if (CHECK_FLAG(vec->flags,
|
||||||
@ -536,9 +571,10 @@ bpacket_reformat_for_peer (struct bpacket *pkt, struct peer_af *paf)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (nhlen == 32 || nhlen == 48) /* 48 == VPN */
|
if (nhlen == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL ||
|
||||||
|
nhlen == BGP_ATTR_NHLEN_VPNV6_GLOBAL_AND_LL)
|
||||||
{
|
{
|
||||||
stream_get_from (&v6nhlocal, s, vec->offset + 1 + (nhlen-IPV6_MAX_BYTELEN), IPV6_MAX_BYTELEN);
|
stream_get_from (&v6nhlocal, s, offset_nhlocal, IPV6_MAX_BYTELEN);
|
||||||
if (IN6_IS_ADDR_UNSPECIFIED (&v6nhlocal))
|
if (IN6_IS_ADDR_UNSPECIFIED (&v6nhlocal))
|
||||||
{
|
{
|
||||||
mod_v6nhl = &peer->nexthop.v6_local;
|
mod_v6nhl = &peer->nexthop.v6_local;
|
||||||
@ -547,9 +583,9 @@ bpacket_reformat_for_peer (struct bpacket *pkt, struct peer_af *paf)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (gnh_modified)
|
if (gnh_modified)
|
||||||
stream_put_in6_addr_at (s, vec->offset + 1, mod_v6nhg);
|
stream_put_in6_addr_at (s, offset_nhglobal, mod_v6nhg);
|
||||||
if (lnh_modified)
|
if (lnh_modified)
|
||||||
stream_put_in6_addr_at (s, vec->offset + 1 + (nhlen-IPV6_MAX_BYTELEN), mod_v6nhl);
|
stream_put_in6_addr_at (s, offset_nhlocal, mod_v6nhl);
|
||||||
|
|
||||||
if (bgp_debug_update(peer, NULL, NULL, 0))
|
if (bgp_debug_update(peer, NULL, NULL, 0))
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user