stream_putw (s, pkt_afi); /* AFI */
stream_putc (s, pkt_safi); /* SAFI */
+ if (nh_afi == AFI_MAX)
+ nh_afi = BGP_NEXTHOP_AFI_FROM_NHLEN(attr->extra->mp_nexthop_len);
/* Nexthop */
switch (nh_afi)
{
size_t mpattrlen_pos = 0;
mpattrlen_pos = bgp_packet_mpattr_start(s, afi, safi,
- (peer_cap_enhe(peer) ? AFI_IP6 : afi),
+ (peer_cap_enhe(peer) ? AFI_IP6 :
+ AFI_MAX), /* get from NH */
vecarr, attr);
bgp_packet_mpattr_prefix(s, afi, safi, p, prd, tag,
addpath_encode, addpath_tx_id);
if (CHECK_FLAG (bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING))
{
- vty_out (vty, "Half-life time: %ld min%s",
- damp->half_life / 60, VTY_NEWLINE);
+ vty_out (vty, "Half-life time: %lld min%s",
+ (long long)damp->half_life / 60, VTY_NEWLINE);
vty_out (vty, "Reuse penalty: %d%s",
- damp->reuse_limit, VTY_NEWLINE);
+ damp->reuse_limit, VTY_NEWLINE);
vty_out (vty, "Suppress penalty: %d%s",
- damp->suppress_value, VTY_NEWLINE);
- vty_out (vty, "Max suppress time: %ld min%s",
- damp->max_suppress_time / 60, VTY_NEWLINE);
+ damp->suppress_value, VTY_NEWLINE);
+ vty_out (vty, "Max suppress time: %lld min%s",
+ (long long)damp->max_suppress_time / 60, VTY_NEWLINE);
vty_out (vty, "Max supress penalty: %u%s",
- damp->ceiling, VTY_NEWLINE);
+ damp->ceiling, VTY_NEWLINE);
vty_out (vty, "%s", VTY_NEWLINE);
}
else
#include "bgpd/rfapi/rfapi_backend.h"
#endif
-#define BGP_VPNVX_HELP_STR \
- "Address Family \n" \
- "Address Family \n"
-
-static int
+extern int
argv_find_and_parse_vpnvx(struct cmd_token **argv, int argc, int *index, afi_t *afi)
{
int ret = 0;
if (prefixlen < VPN_PREFIXLEN_MIN_BYTES*8)
{
- zlog_err ("%s [Error] Update packet error / VPNv4 (prefix length %d less than VPNv4 min length)",
+ zlog_err ("%s [Error] Update packet error / VPN (prefix length %d less than VPN min length)",
peer->host, prefixlen);
return -1;
}
/* sanity check against packet data */
if ((pnt + psize) > lim)
{
- zlog_err ("%s [Error] Update packet error / VPNv4 (prefix length %d exceeds packet size %u)",
+ zlog_err ("%s [Error] Update packet error / VPN (prefix length %d exceeds packet size %u)",
peer->host,
prefixlen, (uint)(lim-pnt));
return -1;
/* sanity check against storage for the IP address portion */
if ((psize - VPN_PREFIXLEN_MIN_BYTES) > (ssize_t) sizeof(p.u))
{
- zlog_err ("%s [Error] Update packet error / VPNv4 (psize %d exceeds storage size %zu)",
+ zlog_err ("%s [Error] Update packet error / VPN (psize %d exceeds storage size %zu)",
peer->host,
prefixlen - VPN_PREFIXLEN_MIN_BYTES*8, sizeof(p.u));
return -1;
/* Sanity check against max bitlen of the address family */
if ((psize - VPN_PREFIXLEN_MIN_BYTES) > prefix_blen (&p))
{
- zlog_err ("%s [Error] Update packet error / VPNv4 (psize %d exceeds family (%u) max byte len %u)",
+ zlog_err ("%s [Error] Update packet error / VPN (psize %d exceeds family (%u) max byte len %u)",
peer->host,
prefixlen - VPN_PREFIXLEN_MIN_BYTES*8,
p.family, prefix_blen (&p));
/* Packet length consistency check. */
if (pnt != lim)
{
- zlog_err ("%s [Error] Update packet error / VPNv4 (%zu data remaining after parsing)",
+ zlog_err ("%s [Error] Update packet error / VPN (%zu data remaining after parsing)",
peer->host, lim - pnt);
return -1;
}
return CMD_SUCCESS;
}
+#ifdef KEEP_OLD_VPN_COMMANDS
DEFUN (show_ip_bgp_vpn_all,
show_ip_bgp_vpn_all_cmd,
"show [ip] bgp <vpnv4|vpnv6>",
}
return CMD_SUCCESS;
}
+#endif /* KEEP_OLD_VPN_COMMANDS */
void
bgp_mplsvpn_init (void)
install_element (BGP_VPNV6_NODE, &no_vpnv6_network_cmd);
install_element (VIEW_NODE, &show_bgp_ip_vpn_rd_cmd);
+#ifdef KEEP_OLD_VPN_COMMANDS
install_element (VIEW_NODE, &show_ip_bgp_vpn_all_cmd);
install_element (VIEW_NODE, &show_ip_bgp_vpn_rd_cmd);
install_element (VIEW_NODE, &show_ip_bgp_vpn_all_tags_cmd);
install_element (VIEW_NODE, &show_ip_bgp_vpn_rd_neighbor_routes_cmd);
install_element (VIEW_NODE, &show_ip_bgp_vpn_all_neighbor_advertised_routes_cmd);
install_element (VIEW_NODE, &show_ip_bgp_vpn_rd_neighbor_advertised_routes_cmd);
+#endif /* KEEP_OLD_VPN_COMMANDS */
}
(label) == MPLS_LABEL_IPV6_EXPLICIT_NULL || \
(label) == MPLS_LABEL_IMPLICIT_NULL)
+#define BGP_VPNVX_HELP_STR \
+ "Address Family \n" \
+ "Address Family \n"
+
struct rd_as
{
u_int16_t type;
extern int str2tag (const char *, u_char *);
extern char *prefix_rd2str (struct prefix_rd *, char *, size_t);
+extern int
+argv_find_and_parse_vpnvx(struct cmd_token **argv, int argc, int *index, afi_t *afi);
+
#endif /* _QUAGGA_BGP_MPLSVPN_H */
SET_FLAG(attr->rmap_change_flags, BATTR_REFLECTED);
#define NEXTHOP_IS_V6 (\
- (safi != SAFI_ENCAP && \
+ (safi != SAFI_ENCAP && safi != SAFI_MPLS_VPN &&\
(p->family == AF_INET6 || peer_cap_enhe(peer))) || \
- (safi == SAFI_ENCAP && attr->extra->mp_nexthop_len == 16))
+ ((safi == SAFI_ENCAP || safi == SAFI_MPLS_VPN) &&\
+ attr->extra->mp_nexthop_len >= IPV6_MAX_BYTELEN))
/* IPv6/MP starts with 1 nexthop. The link-local address is passed only if
* the peer (group) is configured to receive link-local nexthop unchanged
return bgp_peer_counts (vty, peer, AFI_IP, SAFI_UNICAST, uj);
}
-DEFUN (show_ip_bgp_vpnv4_neighbor_prefix_counts,
- show_ip_bgp_vpnv4_neighbor_prefix_counts_cmd,
- "show [ip] bgp vpnv4 all neighbors <A.B.C.D|X:X::X:X|WORD> prefix-counts [json]",
+#ifdef KEEP_OLD_VPN_COMMANDS
+DEFUN (show_ip_bgp_vpn_neighbor_prefix_counts,
+ show_ip_bgp_vpn_neighbor_prefix_counts_cmd,
+ "show [ip] bgp <vpnv4|vpnv6> all neighbors <A.B.C.D|X:X::X:X|WORD> prefix-counts [json]",
SHOW_STR
IP_STR
BGP_STR
- "Address Family\n"
+ BGP_VPNVX_HELP_STR
"Display information about all VPNv4 NLRIs\n"
"Detailed information on TCP and BGP neighbor connections\n"
"Neighbor to display information about\n"
return bgp_peer_counts (vty, peer, AFI_IP, SAFI_MPLS_VPN, uj);
}
-DEFUN (show_ip_bgp_vpnv4_all_route_prefix,
- show_ip_bgp_vpnv4_all_route_prefix_cmd,
- "show [ip] bgp vpnv4 all <A.B.C.D|A.B.C.D/M> [json]",
+DEFUN (show_ip_bgp_vpn_all_route_prefix,
+ show_ip_bgp_vpn_all_route_prefix_cmd,
+ "show [ip] bgp <vpnv4|vpnv6> all <A.B.C.D|A.B.C.D/M> [json]",
SHOW_STR
IP_STR
BGP_STR
- "Address Family\n"
+ BGP_VPNVX_HELP_STR
"Display information about all VPNv4 NLRIs\n"
"Network in the BGP routing table to display\n"
"Network in the BGP routing table to display\n"
network = argv_find (argv, argc, "A.B.C.D/M", &idx) ? argv[idx]->arg : NULL;
return bgp_show_route (vty, NULL, network, AFI_IP, SAFI_MPLS_VPN, NULL, 0, BGP_PATH_ALL, use_json(argc, argv));
}
+#endif /* KEEP_OLD_VPN_COMMANDS */
static void
show_adj_route (struct vty *vty, struct peer *peer, afi_t afi, safi_t safi,
install_element (VIEW_NODE, &show_ip_bgp_neighbor_received_prefix_filter_cmd);
install_element (VIEW_NODE, &show_ip_bgp_dampening_params_cmd);
install_element (VIEW_NODE, &show_ip_bgp_ipv4_dampening_parameters_cmd);
- install_element (VIEW_NODE, &show_ip_bgp_vpnv4_all_route_prefix_cmd);
+#ifdef KEEP_OLD_VPN_COMMANDS
+ install_element (VIEW_NODE, &show_ip_bgp_vpn_all_route_prefix_cmd);
+#endif /* KEEP_OLD_VPN_COMMANDS */
/* BGP dampening clear commands */
install_element (ENABLE_NODE, &clear_ip_bgp_dampening_cmd);
install_element (ENABLE_NODE, &show_ip_bgp_neighbor_prefix_counts_cmd);
install_element (ENABLE_NODE, &show_ip_bgp_instance_neighbor_prefix_counts_cmd);
install_element (ENABLE_NODE, &show_ip_bgp_ipv4_neighbor_prefix_counts_cmd);
- install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_neighbor_prefix_counts_cmd);
+#ifdef KEEP_OLD_VPN_COMMANDS
+ install_element (ENABLE_NODE, &show_ip_bgp_vpn_neighbor_prefix_counts_cmd);
+#endif /* KEEP_OLD_VPN_COMMANDS */
install_element (ENABLE_NODE, &show_bgp_ipv6_neighbor_prefix_counts_cmd);
install_element (ENABLE_NODE, &show_bgp_instance_ipv6_neighbor_prefix_counts_cmd);
u_char tag[3];
};
+#define BGP_NEXTHOP_AFI_FROM_NHLEN(nhlen) \
+ ((nhlen) < IPV4_MAX_BYTELEN ? 0 : \
+ ((nhlen) < IPV6_MAX_BYTELEN ? AFI_IP : AFI_IP6))
+
#define BGP_ATTR_NEXTHOP_AFI_IP6(attr) \
(! CHECK_FLAG (attr->flag, ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP)) && \
(attr)->extra && ((attr)->extra->mp_nexthop_len == 16 || \
route_set_ipv6_nexthop_peer_free
};
-/* `set vpnv4 nexthop A.B.C.D' */
+/* `set ip vpn nexthop A.B.C.D' */
static route_map_result_t
route_set_vpnv4_nexthop (void *rule, struct prefix *prefix,
return address;
}
+/* `set ipv6 vpn nexthop A.B.C.D' */
+
+static route_map_result_t
+route_set_vpnv6_nexthop (void *rule, struct prefix *prefix,
+ route_map_object_t type, void *object)
+{
+ struct in6_addr *address;
+ struct bgp_info *bgp_info;
+
+ if (type == RMAP_BGP)
+ {
+ /* Fetch routemap's rule information. */
+ address = rule;
+ bgp_info = object;
+
+ /* Set next hop value. */
+ memcpy (&(bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_global, address, sizeof(struct in6_addr));
+ (bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_len = BGP_ATTR_NHLEN_VPNV6_GLOBAL;
+ }
+
+ return RMAP_OKAY;
+}
+
+static void *
+route_set_vpnv6_nexthop_compile (const char *arg)
+{
+ int ret;
+ struct in6_addr *address;
+
+ address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in6_addr));
+ ret = inet_pton (AF_INET6, arg, address);
+
+ if (ret == 0)
+ {
+ XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
+ return NULL;
+ }
+
+ return address;
+}
+
static void
-route_set_vpnv4_nexthop_free (void *rule)
+route_set_vpn_nexthop_free (void *rule)
{
XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
}
/* Route map commands for ip nexthop set. */
struct route_map_rule_cmd route_set_vpnv4_nexthop_cmd =
{
- "vpnv4 next-hop",
+ "ip vpn next-hop",
route_set_vpnv4_nexthop,
route_set_vpnv4_nexthop_compile,
- route_set_vpnv4_nexthop_free
+ route_set_vpn_nexthop_free
+};
+
+/* Route map commands for ip nexthop set. */
+struct route_map_rule_cmd route_set_vpnv6_nexthop_cmd =
+{
+ "ipv6 vpn next-hop",
+ route_set_vpnv6_nexthop,
+ route_set_vpnv6_nexthop_compile,
+ route_set_vpn_nexthop_free
};
/* `set originator-id' */
"ipv6 next-hop global", argv[idx_ipv6]->arg);
}
-DEFUN (set_vpnv4_nexthop,
- set_vpnv4_nexthop_cmd,
- "set vpnv4 next-hop A.B.C.D",
+#ifdef KEEP_OLD_VPN_COMMANDS
+DEFUN (set_vpn_nexthop,
+ set_vpn_nexthop_cmd,
+ "set <vpnv4|vpnv6> next-hop [A.B.C.D|X:X::X:X]",
SET_STR
"VPNv4 information\n"
- "VPNv4 next-hop address\n"
- "IP address of next hop\n")
+ "VPNv6 information\n"
+ "VPN next-hop address\n"
+ "IP address of next hop\n"
+ "IPv6 address of next hop\n")
{
- int idx_ipv4 = 3;
- return generic_set_add (vty, VTY_GET_CONTEXT(route_map_index),
- "vpnv4 next-hop", argv[idx_ipv4]->arg);
-}
+ int idx_ip = 3;
+ afi_t afi;
+ int idx = 0;
+ if (argv_find_and_parse_vpnvx (argv, argc, &idx, &afi))
+ {
+ if (afi == AFI_IP)
+ return generic_set_add (vty, VTY_GET_CONTEXT(route_map_index),
+ "ip vpn next-hop", argv[idx_ip]->arg);
+ else
+ return generic_set_add (vty, VTY_GET_CONTEXT(route_map_index),
+ "ipv6 vpn next-hop", argv[idx_ip]->arg);
+ }
+ return CMD_SUCCESS;
+}
-DEFUN (no_set_vpnv4_nexthop,
- no_set_vpnv4_nexthop_cmd,
- "no set vpnv4 next-hop [A.B.C.D]",
+DEFUN (no_set_vpn_nexthop,
+ no_set_vpn_nexthop_cmd,
+ "no set vpn next-hop [A.B.C.D|X:X::X:X]",
NO_STR
SET_STR
- "VPNv4 information\n"
- "VPNv4 next-hop address\n"
- "IP address of next hop\n")
+ "VPN information\n"
+ "VPN next-hop address\n"
+ "IP address of next hop\n"
+ "IPv6 address of next hop\n")
{
- int idx_ipv4 = 4;
- if (argc <= idx_ipv4)
- return generic_set_delete (vty, VTY_GET_CONTEXT(route_map_index),
- "vpnv4 next-hop", NULL);
- return generic_set_delete (vty, VTY_GET_CONTEXT(route_map_index),
- "vpnv4 next-hop", argv[idx_ipv4]->arg);
+ int idx_ip = 4;
+ char *arg;
+ afi_t afi;
+ int idx = 0;
+
+ if (argc <= idx_ip)
+ arg = NULL;
+ else
+ arg = argv[idx_ip]->arg;
+ if (argv_find_and_parse_vpnvx (argv, argc, &idx, &afi))
+ {
+ if (afi == AFI_IP)
+ return generic_set_delete (vty, VTY_GET_CONTEXT(route_map_index),
+ "ip vpn next-hop", arg);
+ else
+ return generic_set_delete (vty, VTY_GET_CONTEXT(route_map_index),
+ "ipv6 vpn next-hop", argv[idx_ip]->arg);
+ }
+ return CMD_SUCCESS;
+}
+#endif /* KEEP_OLD_VPN_COMMANDS */
+
+DEFUN (set_ipx_vpn_nexthop,
+ set_ipx_vpn_nexthop_cmd,
+ "set <ipv4|ipv6> vpn next-hop [A.B.C.D|X:X::X:X]",
+ SET_STR
+ "IPv4 information\n"
+ "IPv6 information\n"
+ "VPN information\n"
+ "VPN next-hop address\n"
+ "IP address of next hop\n"
+ "IPv6 address of next hop\n")
+{
+ int idx_ip = 4;
+ afi_t afi;
+ int idx = 0;
+
+ if (argv_find_and_parse_afi (argv, argc, &idx, &afi))
+ {
+ if (afi == AFI_IP)
+ return generic_set_add (vty, VTY_GET_CONTEXT(route_map_index),
+ "ip vpn next-hop", argv[idx_ip]->arg);
+ else
+ return generic_set_add (vty, VTY_GET_CONTEXT(route_map_index),
+ "ipv6 vpn next-hop", argv[idx_ip]->arg);
+ }
+ return CMD_SUCCESS;
}
+DEFUN (no_set_ipx_vpn_nexthop,
+ no_set_ipx_vpn_nexthop_cmd,
+ "no set <ipv4|ipv6> vpn next-hop [A.B.C.D|X:X::X:X]",
+ NO_STR
+ SET_STR
+ "IPv4 information\n"
+ "IPv6 information\n"
+ "VPN information\n"
+ "VPN next-hop address\n"
+ "IP address of next hop\n"
+ "IPv6 address of next hop\n")
+{
+ int idx_ip = 5;
+ char *arg;
+ afi_t afi;
+ int idx = 0;
+
+ if (argc <= idx_ip)
+ arg = NULL;
+ else
+ arg = argv[idx_ip]->arg;
+ if (argv_find_and_parse_afi (argv, argc, &idx, &afi))
+ {
+ if (afi == AFI_IP)
+ return generic_set_delete (vty, VTY_GET_CONTEXT(route_map_index),
+ "ip vpn next-hop", arg);
+ else
+ return generic_set_delete (vty, VTY_GET_CONTEXT(route_map_index),
+ "ipv6 vpn next-hop", argv[idx_ip]->arg);
+ }
+ return CMD_SUCCESS;
+}
DEFUN (set_originator_id,
set_originator_id_cmd,
route_map_install_set (&route_set_community_cmd);
route_map_install_set (&route_set_community_delete_cmd);
route_map_install_set (&route_set_vpnv4_nexthop_cmd);
+ route_map_install_set (&route_set_vpnv6_nexthop_cmd);
route_map_install_set (&route_set_originator_id_cmd);
route_map_install_set (&route_set_ecommunity_rt_cmd);
route_map_install_set (&route_set_ecommunity_soo_cmd);
install_element (RMAP_NODE, &no_set_ecommunity_rt_cmd);
install_element (RMAP_NODE, &set_ecommunity_soo_cmd);
install_element (RMAP_NODE, &no_set_ecommunity_soo_cmd);
- install_element (RMAP_NODE, &set_vpnv4_nexthop_cmd);
- install_element (RMAP_NODE, &no_set_vpnv4_nexthop_cmd);
+#ifdef KEEP_OLD_VPN_COMMANDS
+ install_element (RMAP_NODE, &set_vpn_nexthop_cmd);
+ install_element (RMAP_NODE, &no_set_vpn_nexthop_cmd);
+#endif /* KEEP_OLD_VPN_COMMANDS */
+ install_element (RMAP_NODE, &set_ipx_vpn_nexthop_cmd);
+ install_element (RMAP_NODE, &no_set_ipx_vpn_nexthop_cmd);
install_element (RMAP_NODE, &set_originator_id_cmd);
install_element (RMAP_NODE, &no_set_originator_id_cmd);
if (CHECK_FLAG (vec->flags, BPKT_ATTRVEC_FLAGS_UPDATED))
{
u_int8_t nhlen;
+ afi_t nhafi = AFI_MAX; /* NH AFI is based on nhlen! */
int route_map_sets_nh;
nhlen = stream_getc_from (s, vec->offset);
-
- if (paf->afi == AFI_IP && !peer_cap_enhe(peer))
+ if (paf->afi == AFI_IP || paf->afi == AFI_IP6)
+ {
+ nhafi = BGP_NEXTHOP_AFI_FROM_NHLEN(nhlen);
+ if (peer_cap_enhe(peer))
+ 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)
{
struct in_addr v4nh, *mod_v4nh;
int nh_modified = 0;
(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_af_flag_check (peer, nhafi, paf->safi,
PEER_FLAG_NEXTHOP_UNCHANGED))
{
+ /* NOTE: not handling case where NH has new AFI */
mod_v4nh = &peer->nexthop.v4;
nh_modified = 1;
}
- if (nh_modified)
- stream_put_in_addr_at (s, vec->offset + 1, mod_v4nh);
+ if (nh_modified) /* allow for VPN RD */
+ stream_put_in_addr_at (s, vec->offset + 1 + nhlen - 4, mod_v4nh);
if (bgp_debug_update(peer, NULL, NULL, 0))
- zlog_debug ("u%" PRIu64 ":s%" PRIu64 " %s send UPDATE w/ nexthop %s",
- PAF_SUBGRP(paf)->update_group->id, PAF_SUBGRP(paf)->id,
- peer->host, inet_ntoa (*mod_v4nh));
-
+ zlog_debug ("u%" PRIu64 ":s%" PRIu64 " %s send UPDATE w/ nexthop %s%s",
+ PAF_SUBGRP(paf)->update_group->id, PAF_SUBGRP(paf)->id,
+ peer->host, inet_ntoa (*mod_v4nh),
+ (nhlen == 12 ? " and RD" : ""));
}
- else if (paf->afi == AFI_IP6 || peer_cap_enhe(peer))
+ else if (nhafi == AFI_IP6)
{
struct in6_addr v6nhglobal, *mod_v6nhg;
struct in6_addr v6nhlocal, *mod_v6nhl;
else if (peer->sort == BGP_PEER_EBGP &&
!CHECK_FLAG(vec->flags,
BPKT_ATTRVEC_FLAGS_RMAP_NH_UNCHANGED) &&
- !peer_af_flag_check (peer, paf->afi, paf->safi,
+ !peer_af_flag_check (peer, nhafi, paf->safi,
PEER_FLAG_NEXTHOP_UNCHANGED))
{
+ /* NOTE: not handling case where NH has new AFI */
mod_v6nhg = &peer->nexthop.v6_global;
gnh_modified = 1;
}
- if (nhlen == 32)
+ if (nhlen == 32 || nhlen == 48) /* 48 == VPN */
{
- stream_get_from (&v6nhlocal, s, vec->offset + 1 + 16, 16);
+ stream_get_from (&v6nhlocal, s, vec->offset + 1 + (nhlen-IPV6_MAX_BYTELEN), IPV6_MAX_BYTELEN);
if (IN6_IS_ADDR_UNSPECIFIED (&v6nhlocal))
{
mod_v6nhl = &peer->nexthop.v6_local;
}
if (gnh_modified)
- stream_put_in6_addr_at (s, vec->offset + 1, mod_v6nhg);
+ stream_put_in6_addr_at (s, vec->offset + 1 + (nhlen-IPV6_MAX_BYTELEN), mod_v6nhg);
if (lnh_modified)
- stream_put_in6_addr_at (s, vec->offset + 1 + 16, mod_v6nhl);
+ stream_put_in6_addr_at (s, vec->offset + 1 + (nhlen-IPV6_MAX_BYTELEN), mod_v6nhl);
if (bgp_debug_update(peer, NULL, NULL, 0))
{
- if (nhlen == 32)
- zlog_debug ("u%" PRIu64 ":s%" PRIu64 " %s send UPDATE w/ mp_nexthops %s, %s",
+ if (nhlen == 32 || nhlen == 48)
+ zlog_debug ("u%" PRIu64 ":s%" PRIu64 " %s send UPDATE w/ mp_nexthops %s, %s%s",
PAF_SUBGRP(paf)->update_group->id,
PAF_SUBGRP(paf)->id,
peer->host,
inet_ntop (AF_INET6, mod_v6nhg, buf, BUFSIZ),
- inet_ntop (AF_INET6, mod_v6nhl, buf2, BUFSIZ));
+ inet_ntop (AF_INET6, mod_v6nhl, buf2, BUFSIZ),
+ (nhlen == 48 ? " and RD" : ""));
else
- zlog_debug ("u%" PRIu64 ":s%" PRIu64 " %s send UPDATE w/ mp_nexthop %s",
+ zlog_debug ("u%" PRIu64 ":s%" PRIu64 " %s send UPDATE w/ mp_nexthop %s%s",
PAF_SUBGRP(paf)->update_group->id,
PAF_SUBGRP(paf)->id,
peer->host,
- inet_ntop (AF_INET6, mod_v6nhg, buf, BUFSIZ));
+ inet_ntop (AF_INET6, mod_v6nhg, buf, BUFSIZ),
+ (nhlen == 24 ? " and RD" : ""));
}
}
}
if (stream_empty (snlri))
mpattrlen_pos = bgp_packet_mpattr_start (snlri, afi, safi,
- (peer_cap_enhe(peer) ? AFI_IP6 : afi),
+ (peer_cap_enhe(peer) ? AFI_IP6 :
+ AFI_MAX), /* get from NH */
&vecarr, adv->baa->attr);
bgp_packet_mpattr_prefix (snlri, afi, safi, &rn->p, prd, tag,
addpath_encode, addpath_tx_id);
return CMD_SUCCESS;
}
+#ifdef KEEP_OLD_VPN_COMMANDS
DEFUN (address_family_vpnv4,
address_family_vpnv4_cmd,
"address-family vpnv4 [unicast]",
vty->node = BGP_VPNV6_NODE;
return CMD_SUCCESS;
}
+#endif /* KEEP_OLD_VPN_COMMANDS */
+
+DEFUN (address_family_ipv4_vpn,
+ address_family_ipv4_vpn_cmd,
+ "address-family ipv4 vpn",
+ "Enter Address Family command mode\n"
+ "Address Family\n"
+ "Subsequent Address Family modifier\n")
+{
+ vty->node = BGP_VPNV4_NODE;
+ return CMD_SUCCESS;
+}
+
+DEFUN (address_family_ipv6_vpn,
+ address_family_ipv6_vpn_cmd,
+ "address-family ipv6 vpn",
+ "Enter Address Family command mode\n"
+ "Address Family\n"
+ "Subsequent Address Family modifier\n")
+{
+ vty->node = BGP_VPNV6_NODE;
+ return CMD_SUCCESS;
+}
DEFUN (address_family_encap,
address_family_encap_cmd,
/* BGP Version. */
json_object_int_add(json_neigh, "bgpVersion", 4);
- json_object_string_add(json_neigh, "remoteRouterId", inet_ntop (AF_INET, &p->remote_id, buf1, BUFSIZ));
+ json_object_string_add(json_neigh, "remoteRouterId",
+ inet_ntop (AF_INET, &p->remote_id, buf1, sizeof(buf1)));
/* Confederation */
if (CHECK_FLAG (bgp->config, BGP_CONFIG_CONFEDERATION) && bgp_confederation_peers_check (bgp, p->as))
/* BGP Version. */
vty_out (vty, " BGP version 4");
- vty_out (vty, ", remote router ID %s%s", inet_ntop (AF_INET, &p->remote_id, buf1, BUFSIZ),
+ vty_out (vty, ", remote router ID %s%s",
+ inet_ntop (AF_INET, &p->remote_id, buf1, sizeof(buf1)),
VTY_NEWLINE);
/* Confederation */
{
if (use_json)
{
- json_object_string_add(json_neigh, "nexthop", inet_ntop (AF_INET, &p->nexthop.v4, buf1, BUFSIZ));
- json_object_string_add(json_neigh, "nexthopGlobal", inet_ntop (AF_INET6, &p->nexthop.v6_global, buf1, BUFSIZ));
- json_object_string_add(json_neigh, "nexthopLocal", inet_ntop (AF_INET6, &p->nexthop.v6_local, buf1, BUFSIZ));
+ json_object_string_add(json_neigh, "nexthop",
+ inet_ntop (AF_INET, &p->nexthop.v4, buf1, sizeof(buf1)));
+ json_object_string_add(json_neigh, "nexthopGlobal",
+ inet_ntop (AF_INET6, &p->nexthop.v6_global, buf1, sizeof(buf1)));
+ json_object_string_add(json_neigh, "nexthopLocal",
+ inet_ntop (AF_INET6, &p->nexthop.v6_local, buf1, sizeof(buf1)));
if (p->shared_network)
json_object_string_add(json_neigh, "bgpConnection", "sharedNetwork");
else
else
{
vty_out (vty, "Nexthop: %s%s",
- inet_ntop (AF_INET, &p->nexthop.v4, buf1, BUFSIZ),
- VTY_NEWLINE);
+ inet_ntop (AF_INET, &p->nexthop.v4, buf1, sizeof(buf1)),
+ VTY_NEWLINE);
vty_out (vty, "Nexthop global: %s%s",
- inet_ntop (AF_INET6, &p->nexthop.v6_global, buf1, BUFSIZ),
- VTY_NEWLINE);
+ inet_ntop (AF_INET6, &p->nexthop.v6_global, buf1, sizeof(buf1)),
+ VTY_NEWLINE);
vty_out (vty, "Nexthop local: %s%s",
- inet_ntop (AF_INET6, &p->nexthop.v6_local, buf1, BUFSIZ),
- VTY_NEWLINE);
+ inet_ntop (AF_INET6, &p->nexthop.v6_local, buf1, sizeof(buf1)),
+ VTY_NEWLINE);
vty_out (vty, "BGP connection: %s%s",
- p->shared_network ? "shared network" : "non shared network",
- VTY_NEWLINE);
+ p->shared_network ? "shared network" : "non shared network",
+ VTY_NEWLINE);
}
}
install_element (BGP_NODE, &address_family_ipv4_safi_cmd);
install_element (BGP_NODE, &address_family_ipv6_cmd);
install_element (BGP_NODE, &address_family_ipv6_safi_cmd);
+#ifdef KEEP_OLD_VPN_COMMANDS
install_element (BGP_NODE, &address_family_vpnv4_cmd);
-
install_element (BGP_NODE, &address_family_vpnv6_cmd);
+#endif /* KEEP_OLD_VPN_COMMANDS */
+ install_element (BGP_NODE, &address_family_ipv4_vpn_cmd);
+ install_element (BGP_NODE, &address_family_ipv6_vpn_cmd);
install_element (BGP_NODE, &address_family_encap_cmd);
install_element (BGP_NODE, &address_family_encapv6_cmd);
else if (safi == SAFI_MULTICAST)
vty_out (vty, "ipv4 multicast");
else if (safi == SAFI_MPLS_VPN)
- vty_out (vty, "vpnv4");
+ vty_out (vty, "ipv4 vpn");
else if (safi == SAFI_ENCAP)
- vty_out (vty, "encap");
+ vty_out (vty, "ipv4 encap");
}
else if (afi == AFI_IP6)
{
else if (safi == SAFI_MULTICAST)
vty_out (vty, "ipv6 multicast");
else if (safi == SAFI_MPLS_VPN)
- vty_out (vty, "vpnv6");
+ vty_out (vty, "ipv6 vpn");
else if (safi == SAFI_ENCAP)
- vty_out (vty, "encapv6");
+ vty_out (vty, "ipv6 encap");
}
vty_out (vty, "%s", VTY_NEWLINE);
bgp_attr_extra_free (&attr);
return;
}
- nexthop = un_addr; /* UN used as MPLS NLRI nexthop */
}
if (local_pref)
break;
case BGP_ENCAP_TYPE_MPLS:
- _RTTO_MAYBE_ADD_ENDPOINT_ADDRESS (mpls);
- bgp_encap_type_mpls_to_tlv (&tto->bgpinfo.mpls, attr);
+ /* nothing to do for MPLS */
break;
case BGP_ENCAP_TYPE_MPLS_IN_GRE:
for (i = 0; i < size && i < RFAPI_DEBUG_BACKTRACE_NENTRIES; ++i)
{
- vnc_zlog_debug_verbose ("backtrace[%2lu]: %s", i, syms[i]);
+ vnc_zlog_debug_verbose ("backtrace[%2zu]: %s", i, syms[i]);
}
free (syms);
rfapiGetTunnelType (attr, &tun_type);
if (p && tun_type == BGP_ENCAP_TYPE_MPLS)
{
- /* MPLS carries UN address in next hop */
- rfapiNexthop2Prefix (attr, p);
- if (p->family != 0)
- return 0;
+ return ENOENT; /* no UN for MPLS */
}
if (attr && attr->extra)
{
if (bi->extra != NULL)
vty_out (vty, " label=%u", decode_label (bi->extra->tag));
- if (rfapiGetVncLifetime (bi->attr, &lifetime))
- {
- if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)
- {
- vty_out (vty, " life=none");
- }
- }
- else
+ if (!rfapiGetVncLifetime (bi->attr, &lifetime))
{
vty_out (vty, " life=%d", lifetime);
}
AS_HELP_STRING([--disable-rr-semantics], [disable the v6 Route Replace semantics]))
AC_ARG_ENABLE([protobuf],
AS_HELP_STRING([--enable-protobuf], [Enable experimental protobuf support]))
+AC_ARG_ENABLE([oldvpn_commands],
+ AS_HELP_STRING([--enable-old-vpn-commands], [Keep old vpn commands]))
AC_CHECK_HEADERS(json-c/json.h)
AC_CHECK_LIB(json-c, json_object_get, LIBS="$LIBS -ljson-c")
fi
fi
+#
+# Logic for old vpn commans support.
+#
+if test "$enable_old_vpn_commands" = "yes"; then
+ AC_DEFINE(KEEP_OLD_VPN_COMMANDS,, [Define for compiling with old vpn commands])
+fi
+
# Fail if the user explicity enabled protobuf support and we couldn't
# find the compiler or libraries.
if test "x$have_protobuf" = "xno" && test "x$enable_protobuf" = "xyes"; then
*list = NULL;
}
+#ifdef linux
static const char *
next_dirname(const char *s)
{
return cur;
}
-#ifdef linux
static void
add_namespace(const char *path)
{
int i = 0, fd;
char bpfdev[128];
struct ifreq ifr;
- u_int blen, immediate, seesent;
+ u_int blen, immediate;
+#ifdef BIOCSSEESENT
+ u_int seesent;
+#endif
struct timeval timeout;
struct bpf_program bpf_prog;
for (i = 0; i < vector_active (comps) && !exists; i++)
{
struct cmd_token *curr = vector_slot (comps, i);
+#ifdef VTYSH_DEBUG
exists = !strcmp (curr->text, token->text) &&
!strcmp (curr->desc, token->desc);
+#else
+ exists = !strcmp (curr->text, token->text);
+#endif /* VTYSH_DEBUG */
}
if (!exists)
void (*slot_run) (void *);
};
+/*
+ * Creates a timer wheel
+ *
+ * master - Thread master structure for the process
+ * period - The Time in seconds that the timer wheel will
+ * take before it starts issuing commands again
+ * for items in each slot
+ * slots - The number of slots to have in this particular
+ * timer wheel
+ * slot_key - A hashing function of some sort that will allow
+ * the timer wheel to put items into individual slots
+ * slot_run - The function to run over each item in a particular slot
+ *
+ * Creates a timer wheel that will wake up 'slots' times over the entire
+ * wheel. Each time the timer wheel wakes up it will iterate through
+ * and run the slot_run function for each item stored in that particular
+ * slot.
+ *
+ * The timer code is 'intelligent' in that it notices if anything is
+ * in a particular slot and can schedule the next timer to skip
+ * the empty slot.
+ *
+ * The general purpose of a timer wheel is to reduce events in a system.
+ * A perfect example of usage for this is say hello packets that need
+ * to be sent out to all your neighbors. Suppose a large routing protocol
+ * has to send keepalive packets every Y seconds to each of it's peers.
+ * At scale we can have a very large number of peers, X.
+ * This means that we will have X timing events every Y seconds.
+ * If you replace these events with a timer wheel that has Z slots
+ * you will have at most Y/Z timer events if each slot has a work item
+ * in it.
+ *
+ * When X is large the number of events in a system can quickly escalate
+ * and cause significant amount of time handling thread events instead
+ * of running your code.
+ */
struct timer_wheel *wheel_init (struct thread_master *master, int period, size_t slots,
unsigned int (*slot_key) (void *),
void (*slot_run) (void *));
+
+/*
+ * Delete the specified timer wheel created
+ */
void wheel_delete (struct timer_wheel *);
/*
int wheel_stop (struct timer_wheel *wheel);
/*
- * Start the wheel from running again
+ * Start the wheel running again
*/
int wheel_start (struct timer_wheel *wheel);
/*
+ * wheel - The Timer wheel being modified
+ * item - The generic data structure that will be handed
+ * to the slot_run function.
+ *
* Add item to a slot setup by the slot_key,
* possibly change next time pop.
*/
int wheel_add_item (struct timer_wheel *wheel, void *item);
/*
+ * wheel - The Timer wheel being modified.
+ * item - The item to remove from one of the slots in
+ * the timer wheel.
+ *
* Remove a item to a slot setup by the slot_key,
* possibly change next time pop.
*/
$ignore{'"address-family ipv4 <unicast|multicast>"'} = "ignore";
$ignore{'"address-family ipv6"'} = "ignore";
$ignore{'"address-family ipv6 <unicast|multicast>"'} = "ignore";
+$ignore{'"address-family ipv4 vpn"'} = "ignore";
$ignore{'"address-family vpnv4"'} = "ignore";
$ignore{'"address-family vpnv4 unicast"'} = "ignore";
$ignore{'"address-family ipv4 vrf NAME"'} = "ignore";
$ignore{'"address-family <encap|encapv4>"'} = "ignore";
$ignore{'"address-family encapv6"'} = "ignore";
+$ignore{'"address-family ipv4 encap"'} = "ignore";
+$ignore{'"address-family ipv6 encap"'} = "ignore";
+$ignore{'"address-family ipv6 vpn"'} = "ignore";
$ignore{'"address-family vpnv6"'} = "ignore";
$ignore{'"address-family vpnv6 unicast"'} = "ignore";
$ignore{'"exit-address-family"'} = "ignore";
#ifdef OPEN_BSD
for (n = 0; n < ifconf.ifc_len; )
{
- int size;
+ unsigned int size;
ifreq = (struct ifreq *)((caddr_t) ifconf.ifc_req + n);
ifp = if_get_by_name_len(ifreq->ifr_name,
int ret;
if (! IS_ZEBRA_DEBUG_RIB)
return;
- ret = rib_lookup_ipv4_route (&p, &gate, VRF_DEFAULT);
+ ret = rib_lookup_ipv4_route ((struct prefix_ipv4 *)&p, &gate, VRF_DEFAULT);
prefix2str (&p, buf, sizeof(buf));
switch (rtm->rtm_type)
{
case ZEBRA_RIB_FOUND_EXACT: /* RIB RR == FIB RR */
zlog_debug ("%s: %s %s: done Ok",
__func__, lookup (rtm_type_str, rtm->rtm_type), buf);
- rib_lookup_and_dump (&p, VRF_DEFAULT);
+ rib_lookup_and_dump ((struct prefix_ipv4 *)&p, VRF_DEFAULT);
return;
break;
}
case ZEBRA_RIB_FOUND_EXACT:
zlog_debug ("%s: %s %s: desync: RR is still in RIB, while already not in FIB",
__func__, lookup (rtm_type_str, rtm->rtm_type), buf);
- rib_lookup_and_dump (&p, VRF_DEFAULT);
+ rib_lookup_and_dump ((struct prefix_ipv4 *)&p, VRF_DEFAULT);
break;
case ZEBRA_RIB_FOUND_CONNECTED:
case ZEBRA_RIB_FOUND_NOGATE:
zlog_debug ("%s: %s %s: desync: RR is still in RIB, plus gate differs",
__func__, lookup (rtm_type_str, rtm->rtm_type), buf);
- rib_lookup_and_dump (&p, VRF_DEFAULT);
+ rib_lookup_and_dump ((struct prefix_ipv4 *)&p, VRF_DEFAULT);
break;
case ZEBRA_RIB_NOTFOUND: /* RIB RR == FIB RR */
zlog_debug ("%s: %s %s: done Ok",
__func__, lookup (rtm_type_str, rtm->rtm_type), buf);
- rib_lookup_and_dump (&p, VRF_DEFAULT);
+ rib_lookup_and_dump ((struct prefix_ipv4 *)&p, VRF_DEFAULT);
return;
break;
}
size_t in_buf_len, fpm_msg_type_e *msg_type)
{
size_t len;
+#ifdef HAVE_NETLINK
int cmd;
+#endif
len = 0;
*msg_type = FPM_MSG_TYPE_NONE;
return NULL;
}
-
+#ifdef HAVE_NETLINK
/* Display default rtm_table for all clients. */
DEFUN (show_table,
show_table_cmd,
zebrad.rtm_table_default = 0;
return CMD_SUCCESS;
}
+#endif
DEFUN (ip_forwarding,
ip_forwarding_cmd,