static struct peer_group *
listen_range_exists (struct bgp *bgp, struct prefix *range, int exact);
+#if 0
+#define INSTALL_CMD_ON_AF_NODES(cmd) \
+ install_element(BGP_IPV4_NODE, cmd); \
+ install_element(BGP_IPV4M_NODE, cmd); \
+ install_element(BGP_IPV4L_NODE, cmd); \
+ install_element(BGP_IPV6_NODE, cmd); \
+ install_element(BGP_IPV6M_NODE, cmd); \
+ install_element(BGP_IPV6L_NODE, cmd); \
+ install_element(BGP_VPNV4_NODE, cmd);
+#endif
+static enum node_type
+bgp_node_type (afi_t afi, safi_t safi)
+{
+ switch (afi)
+ {
+ case AFI_IP:
+ switch (safi)
+ {
+ case SAFI_UNICAST:
+ return BGP_IPV4_NODE;
+ break;
+ case SAFI_MULTICAST:
+ return BGP_IPV4M_NODE;
+ break;
+ case SAFI_LABELED_UNICAST:
+ return BGP_IPV4L_NODE;
+ break;
+ case SAFI_MPLS_VPN:
+ return BGP_VPNV4_NODE;
+ break;
+ case SAFI_ENCAP:
+ return BGP_ENCAP_NODE;
+ break;
+ }
+ break;
+ case AFI_IP6:
+ switch (safi)
+ {
+ case SAFI_UNICAST:
+ return BGP_IPV6_NODE;
+ break;
+ case SAFI_MULTICAST:
+ return BGP_IPV6M_NODE;
+ break;
+ case SAFI_LABELED_UNICAST:
+ return BGP_IPV6L_NODE;
+ break;
+ case SAFI_MPLS_VPN:
+ return BGP_VPNV6_NODE;
+ break;
+ case SAFI_ENCAP:
+ return BGP_ENCAP_NODE;
+ break;
+ }
+ break;
+ case AFI_L2VPN:
+ return BGP_EVPN_NODE;
+ break;
+ case AFI_MAX:
+ // We should never be here but to clarify the switch statement..
+ return BGP_IPV4_NODE;
+ break;
+ }
+
+ // Impossible to happen
+ return BGP_IPV4_NODE;
+}
/* Utility function to get address family from current node. */
afi_t
{
case BGP_IPV6_NODE:
case BGP_IPV6M_NODE:
+ case BGP_IPV6L_NODE:
case BGP_VPNV6_NODE:
case BGP_ENCAPV6_NODE:
afi = AFI_IP6;
case BGP_EVPN_NODE:
safi = SAFI_EVPN;
break;
+ case BGP_IPV4L_NODE:
+ case BGP_IPV6L_NODE:
+ safi = SAFI_LABELED_UNICAST;
+ break;
default:
safi = SAFI_UNICAST;
break;
return ret;
}
-/* supports <unicast|multicast|vpn|encap> */
+/* supports <unicast|multicast|vpn|encap|labeled-unicast> */
safi_t
bgp_vty_safi_from_arg(const char *safi_str)
{
safi = SAFI_ENCAP;
else if (strncmp (safi_str, "v", 1) == 0)
safi = SAFI_MPLS_VPN;
+ else if (strncmp (safi_str, "l", 1) == 0)
+ safi = SAFI_LABELED_UNICAST;
return safi;
}
if (safi)
*safi = SAFI_MULTICAST;
}
+ else if (argv_find (argv, argc, "labeled-unicast", index))
+ {
+ ret = 1;
+ if (safi)
+ *safi = SAFI_LABELED_UNICAST;
+ }
else if (argv_find (argv, argc, "vpn", index))
{
ret = 1;
* that is being parsed.
*
* The show commands are generally of the form:
- * "show [ip] bgp [<view|vrf> WORD] [<ipv4|ipv6> [<unicast|multicast|vpn|encap>]] ..."
+ * "show [ip] bgp [<view|vrf> WORD] [<ipv4|ipv6> [<unicast|multicast|vpn|encap|labeled-unicast>]] ..."
*
* Since we use argv_find if the show command in particular doesn't have:
* [ip]
* [<view|vrf> WORD]
- * [<ipv4|ipv6> [<unicast|multicast|vpn|encap>]]
+ * [<ipv4|ipv6> [<unicast|multicast|vpn|encap|labeled-unicast>]]
* The command parsing should still be ok.
*
* vty -> The vty for the command so we can output some useful data in
if (argv_find (argv, argc, "view", idx) || argv_find (argv, argc, "vrf", idx))
{
vrf_name = argv[*idx + 1]->arg;
- *idx += 2;
if (strmatch (vrf_name, "all"))
*bgp = NULL;
DEFUN_NOSH (address_family_ipv4_safi,
address_family_ipv4_safi_cmd,
- "address-family ipv4 [<unicast|multicast|vpn|encap>]",
+ "address-family ipv4 [<unicast|multicast|vpn|encap|labeled-unicast>]",
"Enter Address Family command mode\n"
"Address Family\n"
BGP_SAFI_HELP_STR)
{
- int idx_safi = 2;
- if (argc == (idx_safi + 1))
+
+ if (argc == 3)
{
- switch (bgp_vty_safi_from_arg(argv[idx_safi]->arg))
- {
- case SAFI_MULTICAST:
- vty->node = BGP_IPV4M_NODE;
- break;
- case SAFI_ENCAP:
- vty->node = BGP_ENCAP_NODE;
- break;
- case SAFI_MPLS_VPN:
- vty->node = BGP_VPNV4_NODE;
- break;
- case SAFI_UNICAST:
- default:
- vty->node = BGP_IPV4_NODE;
- break;
- }
+ safi_t safi = bgp_vty_safi_from_arg(argv[2]->arg);
+ vty->node = bgp_node_type(AFI_IP, safi);
}
else
vty->node = BGP_IPV4_NODE;
DEFUN_NOSH (address_family_ipv6_safi,
address_family_ipv6_safi_cmd,
- "address-family ipv6 [<unicast|multicast|vpn|encap>]",
+ "address-family ipv6 [<unicast|multicast|vpn|encap|labeled-unicast>]",
"Enter Address Family command mode\n"
"Address Family\n"
BGP_SAFI_HELP_STR)
{
- int idx_safi = 2;
- if (argc == (idx_safi + 1))
+ if (argc == 3)
{
- switch (bgp_vty_safi_from_arg(argv[idx_safi]->arg))
- {
- case SAFI_MULTICAST:
- vty->node = BGP_IPV6M_NODE;
- break;
- case SAFI_ENCAP:
- vty->node = BGP_ENCAPV6_NODE;
- break;
- case SAFI_MPLS_VPN:
- vty->node = BGP_VPNV6_NODE;
- break;
- case SAFI_UNICAST:
- default:
- vty->node = BGP_IPV6_NODE;
- break;
- }
+ safi_t safi = bgp_vty_safi_from_arg(argv[2]->arg);
+ vty->node = bgp_node_type(AFI_IP6, safi);
}
else
vty->node = BGP_IPV6_NODE;
{
if (vty->node == BGP_IPV4_NODE
|| vty->node == BGP_IPV4M_NODE
+ || vty->node == BGP_IPV4L_NODE
|| vty->node == BGP_VPNV4_NODE
|| vty->node == BGP_IPV6_NODE
|| vty->node == BGP_IPV6M_NODE
+ || vty->node == BGP_IPV6L_NODE
|| vty->node == BGP_VPNV6_NODE
|| vty->node == BGP_ENCAP_NODE
|| vty->node == BGP_ENCAPV6_NODE
int afi_wildcard = (afi == AFI_MAX);
int safi_wildcard = (safi == SAFI_MAX);
int is_wildcard = (afi_wildcard || safi_wildcard);
+ bool json_output = false;
if (use_json && is_wildcard)
vty_out (vty, "{%s", VTY_NEWLINE);
{
if (bgp_show_summary_afi_safi_peer_exists (bgp, afi, safi))
{
+ json_output = true;
if (is_wildcard)
{
/*
if (use_json && is_wildcard)
vty_out (vty, "}%s", VTY_NEWLINE);
-
+ else if (use_json && !json_output)
+ vty_out (vty, "{}%s", VTY_NEWLINE);
}
static void
return "IPv4 Unicast";
else if (afi == AFI_IP && safi == SAFI_MULTICAST)
return "IPv4 Multicast";
+ else if (afi == AFI_IP && safi == SAFI_LABELED_UNICAST)
+ return "IPv4 labeled-unicast";
else if (afi == AFI_IP && safi == SAFI_MPLS_VPN)
return "IPv4 VPN";
else if (afi == AFI_IP && safi == SAFI_ENCAP)
return "IPv6 Unicast";
else if (afi == AFI_IP6 && safi == SAFI_MULTICAST)
return "IPv6 Multicast";
+ else if (afi == AFI_IP6 && safi == SAFI_LABELED_UNICAST)
+ return "IPv6 labeled-unicast";
else if (afi == AFI_IP6 && safi == SAFI_MPLS_VPN)
return "IPv6 VPN";
else if (afi == AFI_IP6 && safi == SAFI_ENCAP)
return "ipv4Unicast";
else if (afi == AFI_IP && safi == SAFI_MULTICAST)
return "ipv4Multicast";
+ else if (afi == AFI_IP && safi == SAFI_LABELED_UNICAST)
+ return "ipv4LabeledUnicast";
else if (afi == AFI_IP && safi == SAFI_MPLS_VPN)
return "ipv4Vpn";
else if (afi == AFI_IP && safi == SAFI_ENCAP)
return "ipv6Unicast";
else if (afi == AFI_IP6 && safi == SAFI_MULTICAST)
return "ipv6Multicast";
+ else if (afi == AFI_IP6 && safi == SAFI_LABELED_UNICAST)
+ return "ipv6LabeledUnicast";
else if (afi == AFI_IP6 && safi == SAFI_MPLS_VPN)
return "ipv6Vpn";
else if (afi == AFI_IP6 && safi == SAFI_ENCAP)
1,
};
+static struct cmd_node bgp_ipv4_labeled_unicast_node =
+{
+ BGP_IPV4L_NODE,
+ "%s(config-router-af)# ",
+ 1,
+};
+
static struct cmd_node bgp_ipv6_unicast_node =
{
BGP_IPV6_NODE,
1,
};
+static struct cmd_node bgp_ipv6_labeled_unicast_node =
+{
+ BGP_IPV6L_NODE,
+ "%s(config-router-af)# ",
+ 1,
+};
+
static struct cmd_node bgp_vpnv4_node =
{
BGP_VPNV4_NODE,
install_node (&bgp_node, bgp_config_write);
install_node (&bgp_ipv4_unicast_node, NULL);
install_node (&bgp_ipv4_multicast_node, NULL);
+ install_node (&bgp_ipv4_labeled_unicast_node, NULL);
install_node (&bgp_ipv6_unicast_node, NULL);
install_node (&bgp_ipv6_multicast_node, NULL);
+ install_node (&bgp_ipv6_labeled_unicast_node, NULL);
install_node (&bgp_vpnv4_node, NULL);
install_node (&bgp_vpnv6_node, NULL);
install_node (&bgp_encap_node, NULL);
install_default (BGP_NODE);
install_default (BGP_IPV4_NODE);
install_default (BGP_IPV4M_NODE);
+ install_default (BGP_IPV4L_NODE);
install_default (BGP_IPV6_NODE);
install_default (BGP_IPV6M_NODE);
+ install_default (BGP_IPV6L_NODE);
install_default (BGP_VPNV4_NODE);
install_default (BGP_VPNV6_NODE);
install_default (BGP_ENCAP_NODE);
install_element (BGP_IPV6_NODE, &bgp_maxpaths_cmd);
install_element (BGP_IPV6_NODE, &no_bgp_maxpaths_cmd);
install_element (BGP_NODE, &bgp_maxpaths_ibgp_cmd);
- install_element(BGP_NODE, &bgp_maxpaths_ibgp_cluster_cmd);
+ install_element (BGP_NODE, &bgp_maxpaths_ibgp_cluster_cmd);
install_element (BGP_NODE, &no_bgp_maxpaths_ibgp_cmd);
install_element (BGP_IPV4_NODE, &bgp_maxpaths_ibgp_cmd);
- install_element(BGP_IPV4_NODE, &bgp_maxpaths_ibgp_cluster_cmd);
+ install_element (BGP_IPV4_NODE, &bgp_maxpaths_ibgp_cluster_cmd);
install_element (BGP_IPV4_NODE, &no_bgp_maxpaths_ibgp_cmd);
install_element (BGP_IPV6_NODE, &bgp_maxpaths_ibgp_cmd);
- install_element(BGP_IPV6_NODE, &bgp_maxpaths_ibgp_cluster_cmd);
+ install_element (BGP_IPV6_NODE, &bgp_maxpaths_ibgp_cluster_cmd);
install_element (BGP_IPV6_NODE, &no_bgp_maxpaths_ibgp_cmd);
+ install_element (BGP_IPV4L_NODE, &bgp_maxpaths_cmd);
+ install_element (BGP_IPV4L_NODE, &no_bgp_maxpaths_cmd);
+ install_element (BGP_IPV6L_NODE, &bgp_maxpaths_cmd);
+ install_element (BGP_IPV6L_NODE, &no_bgp_maxpaths_cmd);
+
+ install_element (BGP_IPV4L_NODE, &bgp_maxpaths_ibgp_cmd);
+ install_element (BGP_IPV4L_NODE, &bgp_maxpaths_ibgp_cluster_cmd);
+ install_element (BGP_IPV4L_NODE, &no_bgp_maxpaths_ibgp_cmd);
+ install_element (BGP_IPV6L_NODE, &bgp_maxpaths_ibgp_cmd);
+ install_element (BGP_IPV6L_NODE, &bgp_maxpaths_ibgp_cluster_cmd);
+ install_element (BGP_IPV6L_NODE, &no_bgp_maxpaths_ibgp_cmd);
+
/* "timers bgp" commands. */
install_element (BGP_NODE, &bgp_timers_cmd);
install_element (BGP_NODE, &no_bgp_timers_cmd);
install_element (BGP_NODE, &neighbor_activate_cmd);
install_element (BGP_IPV4_NODE, &neighbor_activate_cmd);
install_element (BGP_IPV4M_NODE, &neighbor_activate_cmd);
+ install_element (BGP_IPV4L_NODE, &neighbor_activate_cmd);
install_element (BGP_IPV6_NODE, &neighbor_activate_cmd);
install_element (BGP_IPV6M_NODE, &neighbor_activate_cmd);
+ install_element (BGP_IPV6L_NODE, &neighbor_activate_cmd);
install_element (BGP_VPNV4_NODE, &neighbor_activate_cmd);
install_element (BGP_VPNV6_NODE, &neighbor_activate_cmd);
install_element (BGP_ENCAP_NODE, &neighbor_activate_cmd);
install_element (BGP_NODE, &no_neighbor_activate_cmd);
install_element (BGP_IPV4_NODE, &no_neighbor_activate_cmd);
install_element (BGP_IPV4M_NODE, &no_neighbor_activate_cmd);
+ install_element (BGP_IPV4L_NODE, &no_neighbor_activate_cmd);
install_element (BGP_IPV6_NODE, &no_neighbor_activate_cmd);
install_element (BGP_IPV6M_NODE, &no_neighbor_activate_cmd);
+ install_element (BGP_IPV6L_NODE, &no_neighbor_activate_cmd);
install_element (BGP_VPNV4_NODE, &no_neighbor_activate_cmd);
install_element (BGP_VPNV6_NODE, &no_neighbor_activate_cmd);
install_element (BGP_ENCAP_NODE, &no_neighbor_activate_cmd);
install_element (BGP_NODE, &neighbor_set_peer_group_cmd);
install_element (BGP_IPV4_NODE, &neighbor_set_peer_group_cmd);
install_element (BGP_IPV4M_NODE, &neighbor_set_peer_group_cmd);
+ install_element (BGP_IPV4L_NODE, &neighbor_set_peer_group_cmd);
install_element (BGP_IPV6_NODE, &neighbor_set_peer_group_cmd);
install_element (BGP_IPV6M_NODE, &neighbor_set_peer_group_cmd);
+ install_element (BGP_IPV6L_NODE, &neighbor_set_peer_group_cmd);
install_element (BGP_VPNV4_NODE, &neighbor_set_peer_group_cmd);
install_element (BGP_VPNV6_NODE, &neighbor_set_peer_group_cmd);
install_element (BGP_ENCAP_NODE, &neighbor_set_peer_group_cmd);
install_element (BGP_NODE, &no_neighbor_set_peer_group_cmd);
install_element (BGP_IPV4_NODE, &no_neighbor_set_peer_group_cmd);
install_element (BGP_IPV4M_NODE, &no_neighbor_set_peer_group_cmd);
+ install_element (BGP_IPV4L_NODE, &no_neighbor_set_peer_group_cmd);
install_element (BGP_IPV6_NODE, &no_neighbor_set_peer_group_cmd);
install_element (BGP_IPV6M_NODE, &no_neighbor_set_peer_group_cmd);
+ install_element (BGP_IPV6L_NODE, &no_neighbor_set_peer_group_cmd);
install_element (BGP_VPNV4_NODE, &no_neighbor_set_peer_group_cmd);
install_element (BGP_VPNV6_NODE, &no_neighbor_set_peer_group_cmd);
install_element (BGP_ENCAP_NODE, &no_neighbor_set_peer_group_cmd);
install_element (BGP_NODE, &no_neighbor_soft_reconfiguration_cmd);
install_element (BGP_IPV4_NODE, &neighbor_soft_reconfiguration_cmd);
install_element (BGP_IPV4_NODE, &no_neighbor_soft_reconfiguration_cmd);
+ install_element (BGP_IPV4L_NODE, &neighbor_soft_reconfiguration_cmd);
+ install_element (BGP_IPV4L_NODE, &no_neighbor_soft_reconfiguration_cmd);
install_element (BGP_IPV4M_NODE, &neighbor_soft_reconfiguration_cmd);
install_element (BGP_IPV4M_NODE, &no_neighbor_soft_reconfiguration_cmd);
install_element (BGP_IPV6_NODE, &neighbor_soft_reconfiguration_cmd);
install_element (BGP_IPV6_NODE, &no_neighbor_soft_reconfiguration_cmd);
install_element (BGP_IPV6M_NODE, &neighbor_soft_reconfiguration_cmd);
install_element (BGP_IPV6M_NODE, &no_neighbor_soft_reconfiguration_cmd);
+ install_element (BGP_IPV6L_NODE, &neighbor_soft_reconfiguration_cmd);
+ install_element (BGP_IPV6L_NODE, &no_neighbor_soft_reconfiguration_cmd);
install_element (BGP_VPNV4_NODE, &neighbor_soft_reconfiguration_cmd);
install_element (BGP_VPNV4_NODE, &no_neighbor_soft_reconfiguration_cmd);
install_element (BGP_VPNV6_NODE, &neighbor_soft_reconfiguration_cmd);
install_element (BGP_IPV4_NODE, &no_neighbor_attr_unchanged_cmd);
install_element (BGP_IPV4M_NODE, &neighbor_attr_unchanged_cmd);
install_element (BGP_IPV4M_NODE, &no_neighbor_attr_unchanged_cmd);
+ install_element (BGP_IPV4L_NODE, &neighbor_attr_unchanged_cmd);
+ install_element (BGP_IPV4L_NODE, &no_neighbor_attr_unchanged_cmd);
install_element (BGP_IPV6_NODE, &neighbor_attr_unchanged_cmd);
install_element (BGP_IPV6_NODE, &no_neighbor_attr_unchanged_cmd);
install_element (BGP_IPV6M_NODE, &neighbor_attr_unchanged_cmd);
install_element (BGP_IPV6M_NODE, &no_neighbor_attr_unchanged_cmd);
+ install_element (BGP_IPV6L_NODE, &neighbor_attr_unchanged_cmd);
+ install_element (BGP_IPV6L_NODE, &no_neighbor_attr_unchanged_cmd);
install_element (BGP_VPNV4_NODE, &neighbor_attr_unchanged_cmd);
install_element (BGP_VPNV4_NODE, &no_neighbor_attr_unchanged_cmd);
install_element (BGP_VPNV6_NODE, &neighbor_attr_unchanged_cmd);
install_element (BGP_IPV4_NODE, &no_neighbor_nexthop_self_cmd);
install_element (BGP_IPV4M_NODE, &neighbor_nexthop_self_cmd);
install_element (BGP_IPV4M_NODE, &no_neighbor_nexthop_self_cmd);
+ install_element (BGP_IPV4L_NODE, &neighbor_nexthop_self_cmd);
+ install_element (BGP_IPV4L_NODE, &no_neighbor_nexthop_self_cmd);
install_element (BGP_IPV6_NODE, &neighbor_nexthop_self_cmd);
install_element (BGP_IPV6_NODE, &no_neighbor_nexthop_self_cmd);
install_element (BGP_IPV6M_NODE, &neighbor_nexthop_self_cmd);
install_element (BGP_IPV6M_NODE, &no_neighbor_nexthop_self_cmd);
+ install_element (BGP_IPV6L_NODE, &neighbor_nexthop_self_cmd);
+ install_element (BGP_IPV6L_NODE, &no_neighbor_nexthop_self_cmd);
install_element (BGP_VPNV4_NODE, &neighbor_nexthop_self_cmd);
install_element (BGP_VPNV4_NODE, &no_neighbor_nexthop_self_cmd);
install_element (BGP_VPNV6_NODE, &neighbor_nexthop_self_cmd);
install_element (BGP_IPV4_NODE, &no_neighbor_nexthop_self_force_cmd);
install_element (BGP_IPV4M_NODE, &neighbor_nexthop_self_force_cmd);
install_element (BGP_IPV4M_NODE, &no_neighbor_nexthop_self_force_cmd);
+ install_element (BGP_IPV4L_NODE, &neighbor_nexthop_self_force_cmd);
+ install_element (BGP_IPV4L_NODE, &no_neighbor_nexthop_self_force_cmd);
install_element (BGP_IPV6_NODE, &neighbor_nexthop_self_force_cmd);
install_element (BGP_IPV6_NODE, &no_neighbor_nexthop_self_force_cmd);
install_element (BGP_IPV6M_NODE, &neighbor_nexthop_self_force_cmd);
install_element (BGP_IPV6M_NODE, &no_neighbor_nexthop_self_force_cmd);
+ install_element (BGP_IPV6L_NODE, &neighbor_nexthop_self_force_cmd);
+ install_element (BGP_IPV6L_NODE, &no_neighbor_nexthop_self_force_cmd);
install_element (BGP_VPNV4_NODE, &neighbor_nexthop_self_force_cmd);
install_element (BGP_VPNV4_NODE, &no_neighbor_nexthop_self_force_cmd);
install_element (BGP_VPNV6_NODE, &neighbor_nexthop_self_force_cmd);
install_element (BGP_IPV4_NODE, &no_neighbor_as_override_cmd);
install_element (BGP_IPV4M_NODE, &neighbor_as_override_cmd);
install_element (BGP_IPV4M_NODE, &no_neighbor_as_override_cmd);
+ install_element (BGP_IPV4L_NODE, &neighbor_as_override_cmd);
+ install_element (BGP_IPV4L_NODE, &no_neighbor_as_override_cmd);
install_element (BGP_IPV6_NODE, &neighbor_as_override_cmd);
install_element (BGP_IPV6_NODE, &no_neighbor_as_override_cmd);
install_element (BGP_IPV6M_NODE, &neighbor_as_override_cmd);
install_element (BGP_IPV6M_NODE, &no_neighbor_as_override_cmd);
+ install_element (BGP_IPV6L_NODE, &neighbor_as_override_cmd);
+ install_element (BGP_IPV6L_NODE, &no_neighbor_as_override_cmd);
install_element (BGP_VPNV4_NODE, &neighbor_as_override_cmd);
install_element (BGP_VPNV4_NODE, &no_neighbor_as_override_cmd);
install_element (BGP_VPNV6_NODE, &neighbor_as_override_cmd);
install_element (BGP_IPV4M_NODE, &no_neighbor_remove_private_as_replace_as_cmd);
install_element (BGP_IPV4M_NODE, &neighbor_remove_private_as_all_replace_as_cmd);
install_element (BGP_IPV4M_NODE, &no_neighbor_remove_private_as_all_replace_as_cmd);
+ install_element (BGP_IPV4L_NODE, &neighbor_remove_private_as_cmd);
+ install_element (BGP_IPV4L_NODE, &no_neighbor_remove_private_as_cmd);
+ install_element (BGP_IPV4L_NODE, &neighbor_remove_private_as_all_cmd);
+ install_element (BGP_IPV4L_NODE, &no_neighbor_remove_private_as_all_cmd);
+ install_element (BGP_IPV4L_NODE, &neighbor_remove_private_as_replace_as_cmd);
+ install_element (BGP_IPV4L_NODE, &no_neighbor_remove_private_as_replace_as_cmd);
+ install_element (BGP_IPV4L_NODE, &neighbor_remove_private_as_all_replace_as_cmd);
+ install_element (BGP_IPV4L_NODE, &no_neighbor_remove_private_as_all_replace_as_cmd);
install_element (BGP_IPV6_NODE, &neighbor_remove_private_as_cmd);
install_element (BGP_IPV6_NODE, &no_neighbor_remove_private_as_cmd);
install_element (BGP_IPV6_NODE, &neighbor_remove_private_as_all_cmd);
install_element (BGP_IPV6M_NODE, &no_neighbor_remove_private_as_replace_as_cmd);
install_element (BGP_IPV6M_NODE, &neighbor_remove_private_as_all_replace_as_cmd);
install_element (BGP_IPV6M_NODE, &no_neighbor_remove_private_as_all_replace_as_cmd);
+ install_element (BGP_IPV6L_NODE, &neighbor_remove_private_as_cmd);
+ install_element (BGP_IPV6L_NODE, &no_neighbor_remove_private_as_cmd);
+ install_element (BGP_IPV6L_NODE, &neighbor_remove_private_as_all_cmd);
+ install_element (BGP_IPV6L_NODE, &no_neighbor_remove_private_as_all_cmd);
+ install_element (BGP_IPV6L_NODE, &neighbor_remove_private_as_replace_as_cmd);
+ install_element (BGP_IPV6L_NODE, &no_neighbor_remove_private_as_replace_as_cmd);
+ install_element (BGP_IPV6L_NODE, &neighbor_remove_private_as_all_replace_as_cmd);
+ install_element (BGP_IPV6L_NODE, &no_neighbor_remove_private_as_all_replace_as_cmd);
install_element (BGP_VPNV4_NODE, &neighbor_remove_private_as_cmd);
install_element (BGP_VPNV4_NODE, &no_neighbor_remove_private_as_cmd);
install_element (BGP_VPNV4_NODE, &neighbor_remove_private_as_all_cmd);
install_element (BGP_IPV4M_NODE, &neighbor_send_community_type_cmd);
install_element (BGP_IPV4M_NODE, &no_neighbor_send_community_cmd);
install_element (BGP_IPV4M_NODE, &no_neighbor_send_community_type_cmd);
+ install_element (BGP_IPV4L_NODE, &neighbor_send_community_cmd);
+ install_element (BGP_IPV4L_NODE, &neighbor_send_community_type_cmd);
+ install_element (BGP_IPV4L_NODE, &no_neighbor_send_community_cmd);
+ install_element (BGP_IPV4L_NODE, &no_neighbor_send_community_type_cmd);
install_element (BGP_IPV6_NODE, &neighbor_send_community_cmd);
install_element (BGP_IPV6_NODE, &neighbor_send_community_type_cmd);
install_element (BGP_IPV6_NODE, &no_neighbor_send_community_cmd);
install_element (BGP_IPV6M_NODE, &neighbor_send_community_type_cmd);
install_element (BGP_IPV6M_NODE, &no_neighbor_send_community_cmd);
install_element (BGP_IPV6M_NODE, &no_neighbor_send_community_type_cmd);
+ install_element (BGP_IPV6L_NODE, &neighbor_send_community_cmd);
+ install_element (BGP_IPV6L_NODE, &neighbor_send_community_type_cmd);
+ install_element (BGP_IPV6L_NODE, &no_neighbor_send_community_cmd);
+ install_element (BGP_IPV6L_NODE, &no_neighbor_send_community_type_cmd);
install_element (BGP_VPNV4_NODE, &neighbor_send_community_cmd);
install_element (BGP_VPNV4_NODE, &neighbor_send_community_type_cmd);
install_element (BGP_VPNV4_NODE, &no_neighbor_send_community_cmd);
install_element (BGP_IPV4_NODE, &no_neighbor_route_reflector_client_cmd);
install_element (BGP_IPV4M_NODE, &neighbor_route_reflector_client_cmd);
install_element (BGP_IPV4M_NODE, &no_neighbor_route_reflector_client_cmd);
+ install_element (BGP_IPV4L_NODE, &neighbor_route_reflector_client_cmd);
+ install_element (BGP_IPV4L_NODE, &no_neighbor_route_reflector_client_cmd);
install_element (BGP_IPV6_NODE, &neighbor_route_reflector_client_cmd);
install_element (BGP_IPV6_NODE, &no_neighbor_route_reflector_client_cmd);
install_element (BGP_IPV6M_NODE, &neighbor_route_reflector_client_cmd);
install_element (BGP_IPV6M_NODE, &no_neighbor_route_reflector_client_cmd);
+ install_element (BGP_IPV6L_NODE, &neighbor_route_reflector_client_cmd);
+ install_element (BGP_IPV6L_NODE, &no_neighbor_route_reflector_client_cmd);
install_element (BGP_VPNV4_NODE, &neighbor_route_reflector_client_cmd);
install_element (BGP_VPNV4_NODE, &no_neighbor_route_reflector_client_cmd);
install_element (BGP_VPNV6_NODE, &neighbor_route_reflector_client_cmd);
install_element (BGP_IPV4_NODE, &no_neighbor_route_server_client_cmd);
install_element (BGP_IPV4M_NODE, &neighbor_route_server_client_cmd);
install_element (BGP_IPV4M_NODE, &no_neighbor_route_server_client_cmd);
+ install_element (BGP_IPV4L_NODE, &neighbor_route_server_client_cmd);
+ install_element (BGP_IPV4L_NODE, &no_neighbor_route_server_client_cmd);
install_element (BGP_IPV6_NODE, &neighbor_route_server_client_cmd);
install_element (BGP_IPV6_NODE, &no_neighbor_route_server_client_cmd);
install_element (BGP_IPV6M_NODE, &neighbor_route_server_client_cmd);
install_element (BGP_IPV6M_NODE, &no_neighbor_route_server_client_cmd);
+ install_element (BGP_IPV6L_NODE, &neighbor_route_server_client_cmd);
+ install_element (BGP_IPV6L_NODE, &no_neighbor_route_server_client_cmd);
install_element (BGP_VPNV4_NODE, &neighbor_route_server_client_cmd);
install_element (BGP_VPNV4_NODE, &no_neighbor_route_server_client_cmd);
install_element (BGP_VPNV6_NODE, &neighbor_route_server_client_cmd);
install_element (BGP_IPV4_NODE, &no_neighbor_addpath_tx_all_paths_cmd);
install_element (BGP_IPV4M_NODE, &neighbor_addpath_tx_all_paths_cmd);
install_element (BGP_IPV4M_NODE, &no_neighbor_addpath_tx_all_paths_cmd);
+ install_element (BGP_IPV4L_NODE, &neighbor_addpath_tx_all_paths_cmd);
+ install_element (BGP_IPV4L_NODE, &no_neighbor_addpath_tx_all_paths_cmd);
install_element (BGP_IPV6_NODE, &neighbor_addpath_tx_all_paths_cmd);
install_element (BGP_IPV6_NODE, &no_neighbor_addpath_tx_all_paths_cmd);
install_element (BGP_IPV6M_NODE, &neighbor_addpath_tx_all_paths_cmd);
install_element (BGP_IPV6M_NODE, &no_neighbor_addpath_tx_all_paths_cmd);
+ install_element (BGP_IPV6L_NODE, &neighbor_addpath_tx_all_paths_cmd);
+ install_element (BGP_IPV6L_NODE, &no_neighbor_addpath_tx_all_paths_cmd);
install_element (BGP_VPNV4_NODE, &neighbor_addpath_tx_all_paths_cmd);
install_element (BGP_VPNV4_NODE, &no_neighbor_addpath_tx_all_paths_cmd);
install_element (BGP_VPNV6_NODE, &neighbor_addpath_tx_all_paths_cmd);
install_element (BGP_IPV4_NODE, &no_neighbor_addpath_tx_bestpath_per_as_cmd);
install_element (BGP_IPV4M_NODE, &neighbor_addpath_tx_bestpath_per_as_cmd);
install_element (BGP_IPV4M_NODE, &no_neighbor_addpath_tx_bestpath_per_as_cmd);
+ install_element (BGP_IPV4L_NODE, &neighbor_addpath_tx_bestpath_per_as_cmd);
+ install_element (BGP_IPV4L_NODE, &no_neighbor_addpath_tx_bestpath_per_as_cmd);
install_element (BGP_IPV6_NODE, &neighbor_addpath_tx_bestpath_per_as_cmd);
install_element (BGP_IPV6_NODE, &no_neighbor_addpath_tx_bestpath_per_as_cmd);
install_element (BGP_IPV6M_NODE, &neighbor_addpath_tx_bestpath_per_as_cmd);
install_element (BGP_IPV6M_NODE, &no_neighbor_addpath_tx_bestpath_per_as_cmd);
+ install_element (BGP_IPV6L_NODE, &neighbor_addpath_tx_bestpath_per_as_cmd);
+ install_element (BGP_IPV6L_NODE, &no_neighbor_addpath_tx_bestpath_per_as_cmd);
install_element (BGP_VPNV4_NODE, &neighbor_addpath_tx_bestpath_per_as_cmd);
install_element (BGP_VPNV4_NODE, &no_neighbor_addpath_tx_bestpath_per_as_cmd);
install_element (BGP_VPNV6_NODE, &neighbor_addpath_tx_bestpath_per_as_cmd);
install_element (BGP_IPV4_NODE, &no_neighbor_capability_orf_prefix_cmd);
install_element (BGP_IPV4M_NODE, &neighbor_capability_orf_prefix_cmd);
install_element (BGP_IPV4M_NODE, &no_neighbor_capability_orf_prefix_cmd);
+ install_element (BGP_IPV4L_NODE, &neighbor_capability_orf_prefix_cmd);
+ install_element (BGP_IPV4L_NODE, &no_neighbor_capability_orf_prefix_cmd);
install_element (BGP_IPV6_NODE, &neighbor_capability_orf_prefix_cmd);
install_element (BGP_IPV6_NODE, &no_neighbor_capability_orf_prefix_cmd);
install_element (BGP_IPV6M_NODE, &neighbor_capability_orf_prefix_cmd);
install_element (BGP_IPV6M_NODE, &no_neighbor_capability_orf_prefix_cmd);
+ install_element (BGP_IPV6L_NODE, &neighbor_capability_orf_prefix_cmd);
+ install_element (BGP_IPV6L_NODE, &no_neighbor_capability_orf_prefix_cmd);
/* "neighbor capability dynamic" commands.*/
install_element (BGP_NODE, &neighbor_capability_dynamic_cmd);
install_element (BGP_IPV4M_NODE, &neighbor_default_originate_cmd);
install_element (BGP_IPV4M_NODE, &neighbor_default_originate_rmap_cmd);
install_element (BGP_IPV4M_NODE, &no_neighbor_default_originate_cmd);
+ install_element (BGP_IPV4L_NODE, &neighbor_default_originate_cmd);
+ install_element (BGP_IPV4L_NODE, &neighbor_default_originate_rmap_cmd);
+ install_element (BGP_IPV4L_NODE, &no_neighbor_default_originate_cmd);
install_element (BGP_IPV6_NODE, &neighbor_default_originate_cmd);
install_element (BGP_IPV6_NODE, &neighbor_default_originate_rmap_cmd);
install_element (BGP_IPV6_NODE, &no_neighbor_default_originate_cmd);
install_element (BGP_IPV6M_NODE, &neighbor_default_originate_cmd);
install_element (BGP_IPV6M_NODE, &neighbor_default_originate_rmap_cmd);
install_element (BGP_IPV6M_NODE, &no_neighbor_default_originate_cmd);
+ install_element (BGP_IPV6L_NODE, &neighbor_default_originate_cmd);
+ install_element (BGP_IPV6L_NODE, &neighbor_default_originate_rmap_cmd);
+ install_element (BGP_IPV6L_NODE, &no_neighbor_default_originate_cmd);
/* "neighbor port" commands. */
install_element (BGP_NODE, &neighbor_port_cmd);
install_element (BGP_IPV4_NODE, &no_neighbor_weight_cmd);
install_element (BGP_IPV4M_NODE, &neighbor_weight_cmd);
install_element (BGP_IPV4M_NODE, &no_neighbor_weight_cmd);
+ install_element (BGP_IPV4L_NODE, &neighbor_weight_cmd);
+ install_element (BGP_IPV4L_NODE, &no_neighbor_weight_cmd);
install_element (BGP_IPV6_NODE, &neighbor_weight_cmd);
install_element (BGP_IPV6_NODE, &no_neighbor_weight_cmd);
install_element (BGP_IPV6M_NODE, &neighbor_weight_cmd);
install_element (BGP_IPV6M_NODE, &no_neighbor_weight_cmd);
+ install_element (BGP_IPV6L_NODE, &neighbor_weight_cmd);
+ install_element (BGP_IPV6L_NODE, &no_neighbor_weight_cmd);
install_element (BGP_VPNV4_NODE, &neighbor_weight_cmd);
install_element (BGP_VPNV4_NODE, &no_neighbor_weight_cmd);
install_element (BGP_VPNV6_NODE, &neighbor_weight_cmd);
install_element (BGP_IPV4_NODE, &no_neighbor_distribute_list_cmd);
install_element (BGP_IPV4M_NODE, &neighbor_distribute_list_cmd);
install_element (BGP_IPV4M_NODE, &no_neighbor_distribute_list_cmd);
+ install_element (BGP_IPV4L_NODE, &neighbor_distribute_list_cmd);
+ install_element (BGP_IPV4L_NODE, &no_neighbor_distribute_list_cmd);
install_element (BGP_IPV6_NODE, &neighbor_distribute_list_cmd);
install_element (BGP_IPV6_NODE, &no_neighbor_distribute_list_cmd);
install_element (BGP_IPV6M_NODE, &neighbor_distribute_list_cmd);
install_element (BGP_IPV6M_NODE, &no_neighbor_distribute_list_cmd);
+ install_element (BGP_IPV6L_NODE, &neighbor_distribute_list_cmd);
+ install_element (BGP_IPV6L_NODE, &no_neighbor_distribute_list_cmd);
install_element (BGP_VPNV4_NODE, &neighbor_distribute_list_cmd);
install_element (BGP_VPNV4_NODE, &no_neighbor_distribute_list_cmd);
install_element (BGP_VPNV6_NODE, &neighbor_distribute_list_cmd);
install_element (BGP_IPV4_NODE, &no_neighbor_prefix_list_cmd);
install_element (BGP_IPV4M_NODE, &neighbor_prefix_list_cmd);
install_element (BGP_IPV4M_NODE, &no_neighbor_prefix_list_cmd);
+ install_element (BGP_IPV4L_NODE, &neighbor_prefix_list_cmd);
+ install_element (BGP_IPV4L_NODE, &no_neighbor_prefix_list_cmd);
install_element (BGP_IPV6_NODE, &neighbor_prefix_list_cmd);
install_element (BGP_IPV6_NODE, &no_neighbor_prefix_list_cmd);
install_element (BGP_IPV6M_NODE, &neighbor_prefix_list_cmd);
install_element (BGP_IPV6M_NODE, &no_neighbor_prefix_list_cmd);
+ install_element (BGP_IPV6L_NODE, &neighbor_prefix_list_cmd);
+ install_element (BGP_IPV6L_NODE, &no_neighbor_prefix_list_cmd);
install_element (BGP_VPNV4_NODE, &neighbor_prefix_list_cmd);
install_element (BGP_VPNV4_NODE, &no_neighbor_prefix_list_cmd);
install_element (BGP_VPNV6_NODE, &neighbor_prefix_list_cmd);
install_element (BGP_IPV4_NODE, &no_neighbor_filter_list_cmd);
install_element (BGP_IPV4M_NODE, &neighbor_filter_list_cmd);
install_element (BGP_IPV4M_NODE, &no_neighbor_filter_list_cmd);
+ install_element (BGP_IPV4L_NODE, &neighbor_filter_list_cmd);
+ install_element (BGP_IPV4L_NODE, &no_neighbor_filter_list_cmd);
install_element (BGP_IPV6_NODE, &neighbor_filter_list_cmd);
install_element (BGP_IPV6_NODE, &no_neighbor_filter_list_cmd);
install_element (BGP_IPV6M_NODE, &neighbor_filter_list_cmd);
install_element (BGP_IPV6M_NODE, &no_neighbor_filter_list_cmd);
+ install_element (BGP_IPV6L_NODE, &neighbor_filter_list_cmd);
+ install_element (BGP_IPV6L_NODE, &no_neighbor_filter_list_cmd);
install_element (BGP_VPNV4_NODE, &neighbor_filter_list_cmd);
install_element (BGP_VPNV4_NODE, &no_neighbor_filter_list_cmd);
install_element (BGP_VPNV6_NODE, &neighbor_filter_list_cmd);
install_element (BGP_IPV4_NODE, &no_neighbor_route_map_cmd);
install_element (BGP_IPV4M_NODE, &neighbor_route_map_cmd);
install_element (BGP_IPV4M_NODE, &no_neighbor_route_map_cmd);
+ install_element (BGP_IPV4L_NODE, &neighbor_route_map_cmd);
+ install_element (BGP_IPV4L_NODE, &no_neighbor_route_map_cmd);
install_element (BGP_IPV6_NODE, &neighbor_route_map_cmd);
install_element (BGP_IPV6_NODE, &no_neighbor_route_map_cmd);
install_element (BGP_IPV6M_NODE, &neighbor_route_map_cmd);
install_element (BGP_IPV6M_NODE, &no_neighbor_route_map_cmd);
+ install_element (BGP_IPV6L_NODE, &neighbor_route_map_cmd);
+ install_element (BGP_IPV6L_NODE, &no_neighbor_route_map_cmd);
install_element (BGP_VPNV4_NODE, &neighbor_route_map_cmd);
install_element (BGP_VPNV4_NODE, &no_neighbor_route_map_cmd);
install_element (BGP_VPNV6_NODE, &neighbor_route_map_cmd);
install_element (BGP_IPV4_NODE, &no_neighbor_unsuppress_map_cmd);
install_element (BGP_IPV4M_NODE, &neighbor_unsuppress_map_cmd);
install_element (BGP_IPV4M_NODE, &no_neighbor_unsuppress_map_cmd);
+ install_element (BGP_IPV4L_NODE, &neighbor_unsuppress_map_cmd);
+ install_element (BGP_IPV4L_NODE, &no_neighbor_unsuppress_map_cmd);
install_element (BGP_IPV6_NODE, &neighbor_unsuppress_map_cmd);
install_element (BGP_IPV6_NODE, &no_neighbor_unsuppress_map_cmd);
install_element (BGP_IPV6M_NODE, &neighbor_unsuppress_map_cmd);
install_element (BGP_IPV6M_NODE, &no_neighbor_unsuppress_map_cmd);
+ install_element (BGP_IPV6L_NODE, &neighbor_unsuppress_map_cmd);
+ install_element (BGP_IPV6L_NODE, &no_neighbor_unsuppress_map_cmd);
install_element (BGP_VPNV4_NODE, &neighbor_unsuppress_map_cmd);
install_element (BGP_VPNV4_NODE, &no_neighbor_unsuppress_map_cmd);
install_element (BGP_VPNV6_NODE, &neighbor_unsuppress_map_cmd);
install_element (BGP_IPV4M_NODE, &neighbor_maximum_prefix_restart_cmd);
install_element (BGP_IPV4M_NODE, &neighbor_maximum_prefix_threshold_restart_cmd);
install_element (BGP_IPV4M_NODE, &no_neighbor_maximum_prefix_cmd);
+ install_element (BGP_IPV4L_NODE, &neighbor_maximum_prefix_cmd);
+ install_element (BGP_IPV4L_NODE, &neighbor_maximum_prefix_threshold_cmd);
+ install_element (BGP_IPV4L_NODE, &neighbor_maximum_prefix_warning_cmd);
+ install_element (BGP_IPV4L_NODE, &neighbor_maximum_prefix_threshold_warning_cmd);
+ install_element (BGP_IPV4L_NODE, &neighbor_maximum_prefix_restart_cmd);
+ install_element (BGP_IPV4L_NODE, &neighbor_maximum_prefix_threshold_restart_cmd);
+ install_element (BGP_IPV4L_NODE, &no_neighbor_maximum_prefix_cmd);
install_element (BGP_IPV6_NODE, &neighbor_maximum_prefix_cmd);
install_element (BGP_IPV6_NODE, &neighbor_maximum_prefix_threshold_cmd);
install_element (BGP_IPV6_NODE, &neighbor_maximum_prefix_warning_cmd);
install_element (BGP_IPV6M_NODE, &neighbor_maximum_prefix_restart_cmd);
install_element (BGP_IPV6M_NODE, &neighbor_maximum_prefix_threshold_restart_cmd);
install_element (BGP_IPV6M_NODE, &no_neighbor_maximum_prefix_cmd);
+ install_element (BGP_IPV6L_NODE, &neighbor_maximum_prefix_cmd);
+ install_element (BGP_IPV6L_NODE, &neighbor_maximum_prefix_threshold_cmd);
+ install_element (BGP_IPV6L_NODE, &neighbor_maximum_prefix_warning_cmd);
+ install_element (BGP_IPV6L_NODE, &neighbor_maximum_prefix_threshold_warning_cmd);
+ install_element (BGP_IPV6L_NODE, &neighbor_maximum_prefix_restart_cmd);
+ install_element (BGP_IPV6L_NODE, &neighbor_maximum_prefix_threshold_restart_cmd);
+ install_element (BGP_IPV6L_NODE, &no_neighbor_maximum_prefix_cmd);
install_element (BGP_VPNV4_NODE, &neighbor_maximum_prefix_cmd);
install_element (BGP_VPNV4_NODE, &neighbor_maximum_prefix_threshold_cmd);
install_element (BGP_VPNV4_NODE, &neighbor_maximum_prefix_warning_cmd);
install_element (BGP_IPV4_NODE, &no_neighbor_allowas_in_cmd);
install_element (BGP_IPV4M_NODE, &neighbor_allowas_in_cmd);
install_element (BGP_IPV4M_NODE, &no_neighbor_allowas_in_cmd);
+ install_element (BGP_IPV4L_NODE, &neighbor_allowas_in_cmd);
+ install_element (BGP_IPV4L_NODE, &no_neighbor_allowas_in_cmd);
install_element (BGP_IPV6_NODE, &neighbor_allowas_in_cmd);
install_element (BGP_IPV6_NODE, &no_neighbor_allowas_in_cmd);
install_element (BGP_IPV6M_NODE, &neighbor_allowas_in_cmd);
install_element (BGP_IPV6M_NODE, &no_neighbor_allowas_in_cmd);
+ install_element (BGP_IPV6L_NODE, &neighbor_allowas_in_cmd);
+ install_element (BGP_IPV6L_NODE, &no_neighbor_allowas_in_cmd);
install_element (BGP_VPNV4_NODE, &neighbor_allowas_in_cmd);
install_element (BGP_VPNV4_NODE, &no_neighbor_allowas_in_cmd);
install_element (BGP_VPNV6_NODE, &neighbor_allowas_in_cmd);
/* "exit-address-family" command. */
install_element (BGP_IPV4_NODE, &exit_address_family_cmd);
install_element (BGP_IPV4M_NODE, &exit_address_family_cmd);
+ install_element (BGP_IPV4L_NODE, &exit_address_family_cmd);
install_element (BGP_IPV6_NODE, &exit_address_family_cmd);
install_element (BGP_IPV6M_NODE, &exit_address_family_cmd);
+ install_element (BGP_IPV6L_NODE, &exit_address_family_cmd);
install_element (BGP_VPNV4_NODE, &exit_address_family_cmd);
install_element (BGP_VPNV6_NODE, &exit_address_family_cmd);
install_element (BGP_ENCAP_NODE, &exit_address_family_cmd);
##
AC_PREREQ(2.60)
-AC_INIT(frr, 3.0, [https://github.com/frrouting/frr/issues])
+AC_INIT(frr, 3.1-dev, [https://github.com/frrouting/frr/issues])
PACKAGE_URL="https://frrouting.org/"
PACKAGE_FULLNAME="FRRouting"
AC_SUBST(PACKAGE_FULLNAME)
esac],[tcmalloc_enabled=false])
+dnl Thanks autoconf, but we don't want a default -g -O2. We have our own
+dnl flag determination logic.
+CFLAGS="${CFLAGS:-}"
+
dnl --------------------
dnl Check CC and friends
dnl --------------------
dnl remove autoconf default "-g -O2"
CFLAGS="$orig_cflags"
AC_PROG_CC_C99
+dnl NB: see C11 below
AC_PROG_EGREP
PKG_PROG_PKG_CONFIG
dnl try and enable CFLAGS that are useful for Quagga
dnl - specifically, options to control warnings
-AC_USE_SYSTEM_EXTENSIONS()
+AC_USE_SYSTEM_EXTENSIONS
AC_DEFUN([AC_C_FLAG], [{
AC_LANG_PUSH(C)
ac_c_flag_save="$CFLAGS"
dnl need to do this first so we get useful results for the other options
AC_C_FLAG([-diag-error 10006])
+dnl AC_PROG_CC_C99 may change CC to include -std=gnu99 or something
+ac_cc="$CC"
+CC="${CC% -std=gnu99}"
+CC="${CC% -std=c99}"
+
+AC_C_FLAG([-std=gnu11], [CC="$ac_cc"], [CC="$CC -std=gnu11"])
+
dnl if the user specified any CFLAGS, we don't add "-g -Os/-O2" here
if test "z$orig_cflags" = "z"; then
AC_C_FLAG([-g])
])
AC_LANG_POP(C)
+dnl ----------
+dnl Essentials
+dnl ----------
+
+AX_PTHREAD([
+ CC="$PTHREAD_CC"
+ CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+ LIBS="$PTHREAD_LIBS $LIBS"
+], [
+ AC_MSG_FAILURE([This Quagga version needs pthreads])
+])
+
dnl --------------
dnl Check programs
dnl --------------
AS_HELP_STRING([--enable-ldpd], [build ldpd]))
AC_ARG_ENABLE(nhrpd,
AS_HELP_STRING([--disable-nhrpd], [do not build nhrpd]))
+AC_ARG_ENABLE(eigrpd,
+ AS_HELP_STRING([--disable-eigrpd], [do not build eigrpd]))
AC_ARG_ENABLE(watchfrr,
AS_HELP_STRING([--disable-watchfrr], [do not build watchfrr]))
AC_ARG_ENABLE(isisd,
AS_HELP_STRING([--enable-werror], [enable -Werror (recommended for developers only)]))
AC_ARG_ENABLE(cumulus,
AS_HELP_STRING([--enable-cumulus], [enable Cumulus Switch Special Extensions]))
+AC_ARG_ENABLE(datacenter,
+ AS_HELP_STRING([--enable-datacenter], [enable Compilation for Data Center Extensions]))
AC_ARG_ENABLE(rr-semantics,
AS_HELP_STRING([--disable-rr-semantics], [disable the v6 Route Replace semantics]))
AC_ARG_ENABLE([protobuf],
fi
if test "${enable_poll}" = "yes" ; then
- AC_DEFINE(HAVE_POLL,,Compile systemd support in)
+ AC_DEFINE(HAVE_POLL_CALL,,Compile systemd support in)
fi
dnl ----------
AC_MSG_CHECKING(whether this OS has MPLS stack)
case "$host" in
*-linux*)
- MPLS_METHOD="zebra_mpls_netlink.o"
+ MPLS_METHOD="zebra_mpls_netlink.o zebra_mpls.o"
AC_MSG_RESULT(Linux MPLS)
;;
*-openbsd*)
- MPLS_METHOD="zebra_mpls_openbsd.o"
+ MPLS_METHOD="zebra_mpls_openbsd.o zebra_mpls.o"
AC_MSG_RESULT(OpenBSD MPLS)
;;
*)
esac
AC_SUBST(MPLS_METHOD)
-if test "${enable_cumulus}" = "yes" ; then
- AC_DEFINE(HAVE_CUMULUS,,Compile Special Cumulus Code in)
+if test "${enable_datacenter}" = "yes" ; then
+ AC_DEFINE(HAVE_DATACENTER,,Compile extensions for a DataCenter)
DFLT_NAME="datacenter"
else
DFLT_NAME="traditional"
fi
+
+if test "${enable_cumulus}" = "yes" ; then
+ AC_DEFINE(HAVE_CUMULUS,,Compile Special Cumulus Code in)
+fi
+
AC_SUBST(DFLT_NAME)
AC_DEFINE_UNQUOTED(DFLT_NAME,["$DFLT_NAME"], Name of the configuration default set)
linux/version.h asm/types.h \
sys/cdefs.h])
+ac_stdatomic_ok=false
+AC_DEFINE(FRR_AUTOCONF_ATOMIC, 1, [did autoconf checks for atomic funcs])
+AC_CHECK_HEADER([stdatomic.h],[
+
+ AC_MSG_CHECKING([whether _Atomic qualifier works])
+ AC_LINK_IFELSE([AC_LANG_SOURCE([[
+#include <stdatomic.h>
+int main(int argc, char **argv) {
+ _Atomic int i = 0;
+ return i;
+}
+]])], [
+ AC_DEFINE(HAVE_STDATOMIC_H, 1, [found stdatomic.h])
+ AC_MSG_RESULT([yes])
+ ac_stdatomic_ok=true
+ ], [
+ AC_MSG_RESULT([no])
+ ])
+])
+
+AS_IF([$ac_stdatomic_ok], [true], [
+ AC_MSG_CHECKING([for __atomic_* builtins])
+ AC_LINK_IFELSE([AC_LANG_SOURCE([[
+int main(int argc, char **argv) {
+ volatile int i = 1;
+ __atomic_store_n (&i, 0, __ATOMIC_RELEASE);
+ return __atomic_load_n (&i, __ATOMIC_ACQUIRE);
+}
+]])], [
+ AC_DEFINE(HAVE___ATOMIC, 1, [found __atomic builtins])
+ AC_MSG_RESULT([yes])
+ ], [
+ AC_MSG_RESULT([no])
+
+ dnl FreeBSD 9 has a broken stdatomic.h where _Atomic doesn't work
+ AC_MSG_CHECKING([for __sync_* builtins])
+ AC_LINK_IFELSE([AC_LANG_SOURCE([[
+int main(int argc, char **argv) {
+ volatile int i = 1;
+ __sync_fetch_and_sub (&i, 1);
+ return __sync_val_compare_and_swap (&i, 0, 1);
+}
+]])], [
+ AC_DEFINE(HAVE___SYNC, 1, [found __sync builtins])
+ AC_MSG_RESULT([yes])
+
+ AC_MSG_CHECKING([for __sync_swap builtin])
+ AC_LINK_IFELSE([AC_LANG_SOURCE([[
+int main(int argc, char **argv) {
+ volatile int i = 1;
+ return __sync_swap (&i, 2);
+}
+]])], [
+ AC_DEFINE(HAVE___SYNC_SWAP, 1, [found __sync_swap builtin])
+ AC_MSG_RESULT([yes])
+ ], [
+ AC_MSG_RESULT([no])
+ ])
+
+ ], [
+ AC_MSG_RESULT([no])
+ AC_MSG_FAILURE([stdatomic.h unavailable and $CC has neither __atomic nor __sync builtins])
+ ])
+ ])
+])
+
dnl Utility macro to avoid retyping includes all the time
m4_define([FRR_INCLUDES],
[#ifdef SUNOS_5
fi
AM_CONDITIONAL(NHRPD, test "x$NHRPD" = "xnhrpd")
+if test "${enable_eigrpd}" = "no";then
+ EIGRPD=""
+else
+ EIGRPD="eigrpd"
+fi
+AM_CONDITIONAL(EIGRPD, test "x$EIGRPD" = "xeigrpd")
+
if test "${enable_watchfrr}" = "no";then
WATCHFRR=""
else
AC_SUBST(OSPF6D)
AC_SUBST(LDPD)
AC_SUBST(NHRPD)
+AC_SUBST(EIGRPD)
AC_SUBST(WATCHFRR)
AC_SUBST(ISISD)
AC_SUBST(PIMD)
AC_MSG_RESULT(no)
])
+dnl --------------------------------------
+dnl checking for be32dec existence or not
+dnl --------------------------------------
+AC_CHECK_DECLS([be32enc, be32dec], [], [],
+ [#include <sys/endian.h>])
+
dnl --------------------------------------
dnl checking for clock_time monotonic struct and call
dnl --------------------------------------
ospf6d/Makefile ldpd/Makefile isisd/Makefile vtysh/Makefile
doc/Makefile ospfclient/Makefile tests/Makefile m4/Makefile
pimd/Makefile
+ eigrpd/Makefile
nhrpd/Makefile
redhat/Makefile
tools/Makefile
- cumulus/Makefile
pkgsrc/Makefile
fpm/Makefile
redhat/frr.spec
doc/ospfd.8
doc/ldpd.8
doc/ripd.8
+ doc/eigrpd.8
doc/ripngd.8
doc/pimd.8
doc/nhrpd.8
doc/zebra.8
doc/frr.1
pkgsrc/bgpd.sh pkgsrc/ospf6d.sh pkgsrc/ospfd.sh
- pkgsrc/ripd.sh pkgsrc/ripngd.sh pkgsrc/zebra.sh])
+ pkgsrc/ripd.sh pkgsrc/ripngd.sh pkgsrc/zebra.sh
+ pkgsrc/eigrpd.sh])
if test "${enable_bgp_vnc}" != "no"; then
if test "${with_rfp_path}" = "bgpd/rfp-example" ; then
apt-get install git autoconf automake libtool make gawk libreadline-dev \
texinfo dejagnu pkg-config libpam0g-dev libjson-c-dev bison flex \
- python-pytest libc-ares-dev python3-dev
+ python-pytest libc-ares-dev python3-dev libsystemd-dev
Get FRR, compile it and install it (from Git)
---------------------------------------------
--enable-rtadv \
--enable-tcp-zebra \
--enable-fpm \
+ --enable-systemd=yes \
--with-pkg-git-version \
--with-pkg-extra-version=-MyOwnFRRVersion
make
sudo install -m 644 tools/frr.service /etc/systemd/system/frr.service
sudo install -m 644 cumulus/etc/default/frr /etc/default/frr
sudo install -m 644 cumulus/etc/frr/daemons /etc/frr/daemons
- sudo install -m 644 cumulus/etc/frr/debian.conf /etc/frr/debian.conf
+ sudo install -m 644 cumulus/etc/frr/daemons.conf /etc/frr/daemons.conf
sudo install -m 644 cumulus/etc/frr/Frr.conf /etc/frr/Frr.conf
sudo install -m 644 -o frr -g frr cumulus/etc/frr/vtysh.conf /etc/frr/vtysh.conf
isisd=yes
### Enable the systemd serivce
- Edit `/etc/systemd/system/frr.service` and remove the line **OnFailure=heartbeat-failed@%n.service**
- For example.
+ - systemctl enable frr
- [Unit]
- Description=Cumulus Linux FRR
- After=syslog.target networking.service
- Â Â
### Start the systemd service
- systemctl start frr
- use `systemctl status frr` to check its status.
#include <mach/mach_time.h>
#endif
-/* Relative time, since startup */
+static pthread_mutex_t cpu_record_mtx = PTHREAD_MUTEX_INITIALIZER;
static struct hash *cpu_record = NULL;
static unsigned long
vty_out(vty, "Active Runtime(ms) Invoked Avg uSec Max uSecs");
vty_out(vty, " Avg uSec Max uSecs");
vty_out(vty, " Type Thread%s", VTY_NEWLINE);
- hash_iterate(cpu_record,
- (void(*)(struct hash_backet*,void*))cpu_record_hash_print,
- args);
+
+ pthread_mutex_lock (&cpu_record_mtx);
+ {
+ hash_iterate(cpu_record,
+ (void(*)(struct hash_backet*,void*))cpu_record_hash_print,
+ args);
+ }
+ pthread_mutex_unlock (&cpu_record_mtx);
if (tmp.total_calls > 0)
vty_out_cpu_thread_history(vty, &tmp);
if ( !(a->types & *filter) )
return;
- hash_release (cpu_record, bucket->data);
+ pthread_mutex_lock (&cpu_record_mtx);
+ {
+ hash_release (cpu_record, bucket->data);
+ }
+ pthread_mutex_unlock (&cpu_record_mtx);
}
static void
cpu_record_clear (thread_type filter)
{
thread_type *tmp = &filter;
- hash_iterate (cpu_record,
- (void (*) (struct hash_backet*,void*)) cpu_record_hash_clear,
- tmp);
+
+ pthread_mutex_lock (&cpu_record_mtx);
+ {
+ hash_iterate (cpu_record,
+ (void (*) (struct hash_backet*,void*)) cpu_record_hash_clear,
+ tmp);
+ }
+ pthread_mutex_unlock (&cpu_record_mtx);
}
DEFUN (clear_thread_cpu,
getrlimit(RLIMIT_NOFILE, &limit);
- if (cpu_record == NULL)
- cpu_record
- = hash_create ((unsigned int (*) (void *))cpu_record_hash_key,
- (int (*) (const void *, const void *))cpu_record_hash_cmp);
+ pthread_mutex_lock (&cpu_record_mtx);
+ {
+ if (cpu_record == NULL)
+ cpu_record = hash_create ((unsigned int (*) (void *))cpu_record_hash_key,
+ (int (*) (const void *, const void *))
+ cpu_record_hash_cmp);
+ }
+ pthread_mutex_unlock (&cpu_record_mtx);
rv = XCALLOC (MTYPE_THREAD_MASTER, sizeof (struct thread_master));
if (rv == NULL)
- {
- return NULL;
- }
+ return NULL;
+
+ pthread_mutex_init (&rv->mtx, NULL);
rv->fd_limit = (int)limit.rlim_cur;
rv->read = XCALLOC (MTYPE_THREAD, sizeof (struct thread *) * rv->fd_limit);
rv->background = pqueue_create();
rv->timer->cmp = rv->background->cmp = thread_timer_cmp;
rv->timer->update = rv->background->update = thread_timer_update;
+ rv->spin = true;
+ rv->handle_signals = true;
- #if defined(HAVE_POLL)
+ #if defined(HAVE_POLL_CALL)
rv->handler.pfdsize = rv->fd_limit;
rv->handler.pfdcount = 0;
rv->handler.pfds = XCALLOC (MTYPE_THREAD_MASTER,
void
thread_master_free_unused (struct thread_master *m)
{
- struct thread *t;
- while ((t = thread_trim_head(&m->unuse)) != NULL)
- {
- XFREE(MTYPE_THREAD, t);
- }
+ pthread_mutex_lock (&m->mtx);
+ {
+ struct thread *t;
+ while ((t = thread_trim_head(&m->unuse)) != NULL)
+ {
+ pthread_mutex_destroy (&t->mtx);
+ XFREE(MTYPE_THREAD, t);
+ }
+ }
+ pthread_mutex_unlock (&m->mtx);
}
/* Stop thread scheduler. */
thread_list_free (m, &m->ready);
thread_list_free (m, &m->unuse);
thread_queue_free (m, m->background);
+ pthread_mutex_destroy (&m->mtx);
- #if defined(HAVE_POLL)
+ #if defined(HAVE_POLL_CALL)
XFREE (MTYPE_THREAD_MASTER, m->handler.pfds);
#endif
XFREE (MTYPE_THREAD_MASTER, m);
- if (cpu_record)
- {
- hash_clean (cpu_record, cpu_record_hash_free);
- hash_free (cpu_record);
- cpu_record = NULL;
- }
+ pthread_mutex_lock (&cpu_record_mtx);
+ {
+ if (cpu_record)
+ {
+ hash_clean (cpu_record, cpu_record_hash_free);
+ hash_free (cpu_record);
+ cpu_record = NULL;
+ }
+ }
+ pthread_mutex_unlock (&cpu_record_mtx);
}
/* Return remain time in second. */
unsigned long
thread_timer_remain_second (struct thread *thread)
{
- int64_t remain = monotime_until(&thread->u.sands, NULL) / 1000000LL;
+ int64_t remain;
+
+ pthread_mutex_lock (&thread->mtx);
+ {
+ remain = monotime_until(&thread->u.sands, NULL) / 1000000LL;
+ }
+ pthread_mutex_unlock (&thread->mtx);
+
return remain < 0 ? 0 : remain;
}
thread_timer_remain(struct thread *thread)
{
struct timeval remain;
- monotime_until(&thread->u.sands, &remain);
+ pthread_mutex_lock (&thread->mtx);
+ {
+ monotime_until(&thread->u.sands, &remain);
+ }
+ pthread_mutex_unlock (&thread->mtx);
return remain;
}
if (! thread)
{
thread = XCALLOC (MTYPE_THREAD, sizeof (struct thread));
+ /* mutex only needs to be initialized at struct creation. */
+ pthread_mutex_init (&thread->mtx, NULL);
m->alloc++;
}
+
thread->type = type;
thread->add_type = type;
thread->master = m;
{
tmp.func = func;
tmp.funcname = funcname;
- thread->hist = hash_get (cpu_record, &tmp,
- (void * (*) (void *))cpu_record_hash_alloc);
+ pthread_mutex_lock (&cpu_record_mtx);
+ {
+ thread->hist = hash_get (cpu_record, &tmp,
+ (void * (*) (void *))cpu_record_hash_alloc);
+ }
+ pthread_mutex_unlock (&cpu_record_mtx);
}
thread->hist->total_active++;
thread->func = func;
return thread;
}
- #if defined (HAVE_POLL)
+ #if defined (HAVE_POLL_CALL)
#define fd_copy_fd_set(X) (X)
fd_select (struct thread_master *m, int size, thread_fd_set *read, thread_fd_set *write, thread_fd_set *except, struct timeval *timer_wait)
{
int num;
- #if defined(HAVE_POLL)
+
+ /* If timer_wait is null here, that means either select() or poll() should
+ * block indefinitely, unless the thread_master has overriden it. select()
+ * and poll() differ in the timeout values they interpret as an indefinite
+ * block; select() requires a null pointer, while poll takes a millisecond
+ * value of -1.
+ *
+ * The thread_master owner has the option of overriding the default behavior
+ * by setting ->selectpoll_timeout. If the value is positive, it specifies
+ * the maximum number of milliseconds to wait. If the timeout is -1, it
+ * specifies that we should never wait and always return immediately even if
+ * no event is detected. If the value is zero, the behavior is default.
+ */
+
- /* recalc timeout for poll. Attention NULL pointer is no timeout with
- select, where with poll no timeount is -1 */
+ #if defined(HAVE_POLL_CALL)
int timeout = -1;
- if (timer_wait != NULL)
+
+ if (timer_wait != NULL && m->selectpoll_timeout == 0) // use the default value
timeout = (timer_wait->tv_sec*1000) + (timer_wait->tv_usec/1000);
+ else if (m->selectpoll_timeout > 0) // use the user's timeout
+ timeout = m->selectpoll_timeout;
+ else if (m->selectpoll_timeout < 0) // effect a poll (return immediately)
+ timeout = 0;
num = poll (m->handler.pfds, m->handler.pfdcount + m->handler.pfdcountsnmp, timeout);
#else
+ struct timeval timeout;
+ if (m->selectpoll_timeout > 0) // use the user's timeout
+ {
+ timeout.tv_sec = m->selectpoll_timeout / 1000;
+ timeout.tv_usec = (m->selectpoll_timeout % 1000) * 1000;
+ timer_wait = &timeout;
+ }
+ else if (m->selectpoll_timeout < 0) // effect a poll (return immediately)
+ {
+ timeout.tv_sec = 0;
+ timeout.tv_usec = 0;
+ timer_wait = &timeout;
+ }
num = select (size, read, write, except, timer_wait);
#endif
static int
fd_is_set (struct thread *thread, thread_fd_set *fdset, int pos)
{
- #if defined(HAVE_POLL)
+ #if defined(HAVE_POLL_CALL)
return 1;
#else
return FD_ISSET (THREAD_FD (thread), fdset);
static int
fd_clear_read_write (struct thread *thread)
{
- #if !defined(HAVE_POLL)
+ #if !defined(HAVE_POLL_CALL)
thread_fd_set *fdset = NULL;
int fd = THREAD_FD (thread);
{
struct thread *thread = NULL;
-#if !defined(HAVE_POLL_CALL)
- thread_fd_set *fdset = NULL;
- if (dir == THREAD_READ)
- fdset = &m->handler.readfd;
- else
- fdset = &m->handler.writefd;
-#endif
-
+ pthread_mutex_lock (&m->mtx);
+ {
- #if defined (HAVE_POLL)
+ #if defined (HAVE_POLL_CALL)
- thread = generic_thread_add(m, func, arg, fd, dir, debugargpass);
-
- if (thread == NULL)
- return NULL;
+ thread = generic_thread_add(m, func, arg, fd, dir, debugargpass);
#else
- if (FD_ISSET (fd, fdset))
- {
- zlog_warn ("There is already %s fd [%d]",
- (dir == THREAD_READ) ? "read" : "write", fd);
- return NULL;
- }
+ if (fd >= FD_SETSIZE)
+ {
+ zlog_err ("File descriptor %d is >= FD_SETSIZE (%d). Please recompile"
+ "with --enable-poll=yes", fd, FD_SETSIZE);
+ assert (fd < FD_SETSIZE && !"fd >= FD_SETSIZE");
+ }
+ thread_fd_set *fdset = NULL;
+ if (dir == THREAD_READ)
+ fdset = &m->handler.readfd;
+ else
+ fdset = &m->handler.writefd;
- FD_SET (fd, fdset);
- thread = thread_get (m, dir, func, arg, debugargpass);
+ if (FD_ISSET (fd, fdset))
+ {
+ zlog_warn ("There is already %s fd [%d]",
+ (dir == THREAD_READ) ? "read" : "write", fd);
+ }
+ else
+ {
+ FD_SET (fd, fdset);
+ thread = thread_get (m, dir, func, arg, debugargpass);
+ }
#endif
- thread->u.fd = fd;
- if (dir == THREAD_READ)
- thread_add_fd (m->read, thread);
- else
- thread_add_fd (m->write, thread);
+ if (thread)
+ {
+ pthread_mutex_lock (&thread->mtx);
+ {
+ thread->u.fd = fd;
+ if (dir == THREAD_READ)
+ thread_add_fd (m->read, thread);
+ else
+ thread_add_fd (m->write, thread);
+ }
+ pthread_mutex_unlock (&thread->mtx);
+ }
+ }
+ pthread_mutex_unlock (&m->mtx);
return thread;
}
assert (type == THREAD_TIMER || type == THREAD_BACKGROUND);
assert (time_relative);
- queue = ((type == THREAD_TIMER) ? m->timer : m->background);
- thread = thread_get (m, type, func, arg, debugargpass);
+ pthread_mutex_lock (&m->mtx);
+ {
+ queue = ((type == THREAD_TIMER) ? m->timer : m->background);
+ thread = thread_get (m, type, func, arg, debugargpass);
- monotime(&thread->u.sands);
- timeradd(&thread->u.sands, time_relative, &thread->u.sands);
+ pthread_mutex_lock (&thread->mtx);
+ {
+ monotime(&thread->u.sands);
+ timeradd(&thread->u.sands, time_relative, &thread->u.sands);
+ pqueue_enqueue(thread, queue);
+ }
+ pthread_mutex_unlock (&thread->mtx);
+ }
+ pthread_mutex_unlock (&m->mtx);
- pqueue_enqueue(thread, queue);
return thread;
}
assert (m != NULL);
- thread = thread_get (m, THREAD_EVENT, func, arg, debugargpass);
- thread->u.val = val;
- thread_list_add (&m->event, thread);
+ pthread_mutex_lock (&m->mtx);
+ {
+ thread = thread_get (m, THREAD_EVENT, func, arg, debugargpass);
+ pthread_mutex_lock (&thread->mtx);
+ {
+ thread->u.val = val;
+ thread_list_add (&m->event, thread);
+ }
+ pthread_mutex_unlock (&thread->mtx);
+ }
+ pthread_mutex_unlock (&m->mtx);
return thread;
}
static void
thread_cancel_read_or_write (struct thread *thread, short int state)
{
- #if defined(HAVE_POLL)
+ #if defined(HAVE_POLL_CALL)
nfds_t i;
for (i=0;i<thread->master->handler.pfdcount;++i)
fd_clear_read_write (thread);
}
-/* Cancel thread from scheduler. */
+/**
+ * Cancel thread from scheduler.
+ *
+ * This function is *NOT* MT-safe. DO NOT call it from any other pthread except
+ * the one which owns thread->master.
+ */
void
thread_cancel (struct thread *thread)
{
struct thread_list *list = NULL;
struct pqueue *queue = NULL;
struct thread **thread_array = NULL;
-
+
+ pthread_mutex_lock (&thread->master->mtx);
+ pthread_mutex_lock (&thread->mtx);
+
switch (thread->type)
{
case THREAD_READ:
- #if defined (HAVE_POLL)
+ #if defined (HAVE_POLL_CALL)
thread_cancel_read_or_write (thread, POLLIN | POLLHUP);
#else
thread_cancel_read_or_write (thread, 0);
thread_array = thread->master->read;
break;
case THREAD_WRITE:
- #if defined (HAVE_POLL)
+ #if defined (HAVE_POLL_CALL)
thread_cancel_read_or_write (thread, POLLOUT | POLLHUP);
#else
thread_cancel_read_or_write (thread, 0);
queue = thread->master->background;
break;
default:
- return;
+ goto done;
break;
}
if (queue)
{
assert(thread->index >= 0);
- assert(thread == queue->array[thread->index]);
- pqueue_remove_at(thread->index, queue);
+ pqueue_remove (thread, queue);
}
else if (list)
{
}
thread_add_unuse (thread->master, thread);
+
+done:
+ pthread_mutex_unlock (&thread->mtx);
+ pthread_mutex_unlock (&thread->master->mtx);
}
/* Delete all events which has argument value arg. */
{
unsigned int ret = 0;
struct thread *thread;
+ struct thread *t;
- thread = m->event.head;
- while (thread)
- {
- struct thread *t;
-
- t = thread;
- thread = t->next;
-
- if (t->arg == arg)
+ pthread_mutex_lock (&m->mtx);
+ {
+ thread = m->event.head;
+ while (thread)
+ {
+ t = thread;
+ pthread_mutex_lock (&t->mtx);
{
- ret++;
- thread_list_delete (&m->event, t);
- thread_add_unuse (m, t);
+ thread = t->next;
+
+ if (t->arg == arg)
+ {
+ ret++;
+ thread_list_delete (&m->event, t);
+ thread_add_unuse (m, t);
+ }
}
- }
-
- /* thread can be on the ready list too */
- thread = m->ready.head;
- while (thread)
- {
- struct thread *t;
-
- t = thread;
- thread = t->next;
+ pthread_mutex_unlock (&t->mtx);
+ }
- if (t->arg == arg)
+ /* thread can be on the ready list too */
+ thread = m->ready.head;
+ while (thread)
+ {
+ t = thread;
+ pthread_mutex_lock (&t->mtx);
{
- ret++;
- thread_list_delete (&m->ready, t);
- thread_add_unuse (m, t);
+ thread = t->next;
+
+ if (t->arg == arg)
+ {
+ ret++;
+ thread_list_delete (&m->ready, t);
+ thread_add_unuse (m, t);
+ }
}
- }
+ pthread_mutex_unlock (&t->mtx);
+ }
+ }
+ pthread_mutex_unlock (&m->mtx);
return ret;
}
thread_delete_fd (thread_array, thread);
thread_list_add (&m->ready, thread);
thread->type = THREAD_READY;
- #if defined(HAVE_POLL)
+ #if defined(HAVE_POLL_CALL)
thread->master->handler.pfds[pos].events &= ~(state);
#endif
return 1;
return 0;
}
- #if defined(HAVE_POLL)
+ #if defined(HAVE_POLL_CALL)
/* check poll events */
static void
static void
thread_process_fds (struct thread_master *m, thread_fd_set *rset, thread_fd_set *wset, int num)
{
- #if defined (HAVE_POLL)
+ #if defined (HAVE_POLL_CALL)
check_pollfds (m, rset, num);
#else
int ready = 0, index;
struct timeval *timer_wait = &timer_val;
struct timeval *timer_wait_bg;
- while (1)
+ do
{
int num = 0;
/* Signals pre-empt everything */
- quagga_sigevent_process ();
+ if (m->handle_signals)
+ quagga_sigevent_process ();
+ pthread_mutex_lock (&m->mtx);
/* Drain the ready queue of already scheduled jobs, before scheduling
* more.
*/
if ((thread = thread_trim_head (&m->ready)) != NULL)
- return thread_run (m, thread, fetch);
+ {
+ fetch = thread_run (m, thread, fetch);
+ pthread_mutex_unlock (&m->mtx);
+ return fetch;
+ }
/* To be fair to all kinds of threads, and avoid starvation, we
* need to be careful to consider all thread types for scheduling
thread_process (&m->event);
/* Structure copy. */
- #if !defined(HAVE_POLL)
+ #if !defined(HAVE_POLL_CALL)
readfd = fd_copy_fd_set(m->handler.readfd);
writefd = fd_copy_fd_set(m->handler.writefd);
exceptfd = fd_copy_fd_set(m->handler.exceptfd);
if (num < 0)
{
if (errno == EINTR)
- continue; /* signal received - process it */
+ {
+ pthread_mutex_unlock (&m->mtx);
+ continue; /* signal received - process it */
+ }
zlog_warn ("select() error: %s", safe_strerror (errno));
+ pthread_mutex_unlock (&m->mtx);
return NULL;
}
list at this time. If this is code is uncommented, then background
timer threads will not run unless there is nothing else to do. */
if ((thread = thread_trim_head (&m->ready)) != NULL)
- return thread_run (m, thread, fetch);
+ {
+ fetch = thread_run (m, thread, fetch);
+ pthread_mutex_unlock (&m->mtx);
+ return fetch;
+ }
#endif
/* Background timer/events, lowest priority */
thread_timer_process (m->background, &now);
if ((thread = thread_trim_head (&m->ready)) != NULL)
- return thread_run (m, thread, fetch);
- }
+ {
+ fetch = thread_run (m, thread, fetch);
+ pthread_mutex_unlock (&m->mtx);
+ return fetch;
+ }
+
+ pthread_mutex_unlock (&m->mtx);
+
+ } while (m->spin);
+
+ return NULL;
}
unsigned long
int
thread_should_yield (struct thread *thread)
{
- return monotime_since(&thread->real, NULL) > (int64_t)thread->yield;
+ int result;
+ pthread_mutex_lock (&thread->mtx);
+ {
+ result = monotime_since(&thread->real, NULL) > (int64_t)thread->yield;
+ }
+ pthread_mutex_unlock (&thread->mtx);
+ return result;
}
void
thread_set_yield_time (struct thread *thread, unsigned long yield_time)
{
- thread->yield = yield_time;
+ pthread_mutex_lock (&thread->mtx);
+ {
+ thread->yield = yield_time;
+ }
+ pthread_mutex_unlock (&thread->mtx);
}
void
memset (&dummy, 0, sizeof (struct thread));
+ pthread_mutex_init (&dummy.mtx, NULL);
dummy.type = THREAD_EVENT;
dummy.add_type = THREAD_EXECUTE;
dummy.master = NULL;
tmp.func = dummy.func = func;
tmp.funcname = dummy.funcname = funcname;
- dummy.hist = hash_get (cpu_record, &tmp,
- (void * (*) (void *))cpu_record_hash_alloc);
+ pthread_mutex_lock (&cpu_record_mtx);
+ {
+ dummy.hist = hash_get (cpu_record, &tmp,
+ (void * (*) (void *))cpu_record_hash_alloc);
+ }
+ pthread_mutex_unlock (&cpu_record_mtx);
dummy.schedfrom = schedfrom;
dummy.schedfrom_line = fromln;
#include <zebra.h>
#include "monotime.h"
+#include <pthread.h>
struct rusage_t
{
*/
typedef fd_set thread_fd_set;
- #if defined(HAVE_POLL)
+ #if defined(HAVE_POLL_CALL)
#include <poll.h>
struct fd_handler
{
int fd_limit;
struct fd_handler handler;
unsigned long alloc;
+ long selectpoll_timeout;
+ bool spin;
+ bool handle_signals;
+ pthread_mutex_t mtx;
};
typedef unsigned char thread_type;
const char *funcname;
const char *schedfrom;
int schedfrom_line;
+ pthread_mutex_t mtx;
};
struct cpu_thread_history
return CMD_WARNING;
}
- if (argc > 1)
+ if (argc > 3)
{
if (strncmp (argv[3]->text, "translate-c", 11) == 0)
ospf_area_nssa_translator_role_set (ospf, area_id,
{
VTY_DECLVAR_CONTEXT(interface, ifp);
int idx_ipv4 = argc - 1;
- struct in_addr addr;
+ struct in_addr addr = { .s_addr = 0L};
int ret;
struct ospf_if_params *params;
struct ospf_interface *oi;
int idx = 0;
struct in_addr addr;
struct ospf_if_params *params;
+
params = IF_DEF_PARAMS (ifp);
if (argv_find (argv, argc, "A.B.C.D", &idx))
mloop = pim_socket_mcastloop_get(pim_ifp->pim_sock_fd);
if (uj) {
+ char pbuf[PREFIX2STR_BUFFER];
json_row = json_object_new_object();
json_object_pim_ifp_add(json_row, ifp);
sec_list = json_object_new_array();
for (ALL_LIST_ELEMENTS_RO(pim_ifp->sec_addr_list, sec_node, sec_addr)) {
- json_object_array_add(sec_list, json_object_new_string(inet_ntoa(sec_addr->addr)));
+ json_object_array_add(sec_list,
+ json_object_new_string(prefix2str(&sec_addr->addr,
+ pbuf,
+ sizeof(pbuf))));
}
json_object_object_add(json_row, "secondaryAddressList", sec_list);
}
vty_out(vty, "Use Source : %s%s", inet_ntoa(pim_ifp->update_source), VTY_NEWLINE);
}
if (pim_ifp->sec_addr_list) {
+ char pbuf[PREFIX2STR_BUFFER];
vty_out(vty, "Address : %s (primary)%s",
- inet_ntoa(ifaddr), VTY_NEWLINE);
+ inet_ntoa(ifaddr), VTY_NEWLINE);
for (ALL_LIST_ELEMENTS_RO(pim_ifp->sec_addr_list, sec_node, sec_addr)) {
vty_out(vty, " %s%s",
- inet_ntoa(sec_addr->addr), VTY_NEWLINE);
+ prefix2str(&sec_addr->addr,
+ pbuf,
+ sizeof(pbuf)), VTY_NEWLINE);
}
} else {
vty_out(vty, "Address : %s%s", inet_ntoa(ifaddr), VTY_NEWLINE);
neigh_src_str, sizeof(neigh_src_str));
for (ALL_LIST_ELEMENTS_RO(neigh->prefix_list, prefix_node, p)) {
- char neigh_sec_str[INET_ADDRSTRLEN];
+ char neigh_sec_str[PREFIX2STR_BUFFER];
- if (p->family != AF_INET)
- continue;
-
- pim_inet4_dump("<src?>", p->u.prefix4,
- neigh_sec_str, sizeof(neigh_sec_str));
+ prefix2str(p, neigh_sec_str, sizeof(neigh_sec_str));
vty_out(vty, "%-9s %-15s %-15s %-15s%s",
ifp->name,
return CMD_SUCCESS;
}
+DEFUN (ip_pim_v6_secondary,
+ ip_pim_v6_secondary_cmd,
+ "ip pim send-v6-secondary",
+ IP_STR
+ "pim multicast routing\n"
+ "Send v6 secondary addresses\n")
+{
+ pimg->send_v6_secondary = 1;
+
+ return CMD_SUCCESS;
+}
+
+DEFUN (no_ip_pim_v6_secondary,
+ no_ip_pim_v6_secondary_cmd,
+ "no ip pim send-v6-secondary",
+ NO_STR
+ IP_STR
+ "pim multicast routing\n"
+ "Send v6 secondary addresses\n")
+{
+ pimg->send_v6_secondary = 0;
+
+ return CMD_SUCCESS;
+}
+
DEFUN (ip_pim_rp,
ip_pim_rp_cmd,
"ip pim rp A.B.C.D [A.B.C.D/M]",
"ip address of RP\n"
"Group Address range to cover\n")
{
- int idx_ipv4 = 4;
+ int idx_ipv4 = 4, idx_group = 0;
- if (argc == (idx_ipv4 + 1))
- return pim_no_rp_cmd_worker (vty, argv[idx_ipv4]->arg, NULL, NULL);
+ if (argv_find (argv, argc, "A.B.C.D/M", &idx_group))
+ return pim_no_rp_cmd_worker (vty, argv[idx_ipv4]->arg, argv[idx_group]->arg, NULL);
else
- return pim_no_rp_cmd_worker (vty, argv[idx_ipv4]->arg, argv[idx_ipv4 + 1]->arg, NULL);
+ return pim_no_rp_cmd_worker (vty, argv[idx_ipv4]->arg, NULL, NULL);
}
DEFUN (no_ip_pim_rp_prefix_list,
int idx_ipv4 = 2;
int result;
struct in_addr source_addr;
- const char *source_str = (argc == idx_ipv4) ? argv[idx_ipv4]->arg : "0.0.0.0";
+ const char *source_str = (argc == 3) ? argv[idx_ipv4]->arg : "0.0.0.0";
result = inet_pton(AF_INET, source_str, &source_addr);
if (result <= 0) {
int idx_ipv4 = 3;
int result;
struct in_addr source_addr;
- const char *source_str = (argc == idx_ipv4) ? argv[idx_ipv4]->arg : "0.0.0.0";
+ const char *source_str = (argc == 4) ? argv[idx_ipv4]->arg : "0.0.0.0";
result = inet_pton(AF_INET, source_str, &source_addr);
if (result <= 0) {
"Enable PIM ECMP \n"
"Enable PIM ECMP Rebalance\n")
{
+ qpim_ecmp_enable = 1;
qpim_ecmp_rebalance_enable = 1;
return CMD_SUCCESS;
"mesh group source\n"
"mesh group local address\n")
{
- if (argc == 6)
+ if (argc == 7)
return ip_no_msdp_mesh_group_cmd_worker(vty, argv[6]->arg);
else
return ip_no_msdp_mesh_group_source_cmd_worker(vty, argv[4]->arg);
"JavaScript Object Notation\n")
{
u_char uj = use_json(argc, argv);
- if (uj)
- argc--;
- if (argc == 6)
- ip_msdp_show_sa_sg(vty, argv[4]->arg, argv[5]->arg, uj);
- else if (argc == 5)
- ip_msdp_show_sa_addr(vty, argv[4]->arg, uj);
+ int idx = 0;
+ char *src_ip = argv_find (argv, argc, "A.B.C.D", &idx) ? argv[idx++]->arg : NULL;
+ char *grp_ip = idx < argc && argv_find (argv, argc, "A.B.C.D", &idx) ?
+ argv[idx]->arg : NULL;
+
+ if (src_ip && grp_ip)
+ ip_msdp_show_sa_sg(vty, src_ip, grp_ip, uj);
+ else if (src_ip)
+ ip_msdp_show_sa_addr(vty, src_ip, uj);
else
ip_msdp_show_sa(vty, uj);
install_element (CONFIG_NODE, &no_ip_pim_keep_alive_cmd);
install_element (CONFIG_NODE, &ip_pim_packets_cmd);
install_element (CONFIG_NODE, &no_ip_pim_packets_cmd);
+ install_element (CONFIG_NODE, &ip_pim_v6_secondary_cmd);
+ install_element (CONFIG_NODE, &no_ip_pim_v6_secondary_cmd);
install_element (CONFIG_NODE, &ip_ssmpingd_cmd);
install_element (CONFIG_NODE, &no_ip_ssmpingd_cmd);
install_element (CONFIG_NODE, &ip_msdp_peer_cmd);
static int pim_iface_vif_index[MAXVIFS];
static void pim_if_igmp_join_del_all(struct interface *ifp);
+ static int igmp_join_sock(const char *ifname, ifindex_t ifindex,
+ struct in_addr group_addr, struct in_addr source_addr);
void
pim_if_init (void)
const struct pim_secondary_addr *sec1 = p1;
const struct pim_secondary_addr *sec2 = p2;
- if (ntohl(sec1->addr.s_addr) < ntohl(sec2->addr.s_addr))
+ if (sec1->addr.family == AF_INET &&
+ sec2->addr.family == AF_INET6)
return -1;
- if (ntohl(sec1->addr.s_addr) > ntohl(sec2->addr.s_addr))
+ if (sec1->addr.family == AF_INET6 &&
+ sec2->addr.family == AF_INET)
return 1;
+ if (sec1->addr.family == AF_INET)
+ {
+ if (ntohl(sec1->addr.u.prefix4.s_addr) < ntohl(sec2->addr.u.prefix4.s_addr))
+ return -1;
+
+ if (ntohl(sec1->addr.u.prefix4.s_addr) > ntohl(sec2->addr.u.prefix4.s_addr))
+ return 1;
+ }
+ else
+ {
+ return memcmp (&sec1->addr.u.prefix6,
+ &sec2->addr.u.prefix6,
+ sizeof (struct in6_addr));
+ }
+
return 0;
}
}
static struct pim_secondary_addr *
-pim_sec_addr_find(struct pim_interface *pim_ifp, struct in_addr addr)
+pim_sec_addr_find(struct pim_interface *pim_ifp, struct prefix *addr)
{
struct pim_secondary_addr *sec_addr;
struct listnode *node;
}
for (ALL_LIST_ELEMENTS_RO(pim_ifp->sec_addr_list, node, sec_addr)) {
- if (sec_addr->addr.s_addr == addr.s_addr) {
+ if (prefix_cmp(&sec_addr->addr, addr)) {
return sec_addr;
}
}
pim_sec_addr_free(sec_addr);
}
-static int pim_sec_addr_add(struct pim_interface *pim_ifp, struct in_addr addr)
+static int pim_sec_addr_add(struct pim_interface *pim_ifp, struct prefix *addr)
{
int changed = 0;
struct pim_secondary_addr *sec_addr;
}
changed = 1;
- sec_addr->addr = addr;
+ sec_addr->addr = *addr;
listnode_add_sort(pim_ifp->sec_addr_list, sec_addr);
return changed;
for (ALL_LIST_ELEMENTS_RO(ifp->connected, node, ifc)) {
struct prefix *p = ifc->address;
- if (p->family != AF_INET) {
- continue;
- }
-
if (PIM_INADDR_IS_ANY(p->u.prefix4)) {
continue;
}
continue;
}
- if (pim_sec_addr_add(pim_ifp, p->u.prefix4)) {
+ if (pim_sec_addr_add(pim_ifp, p)) {
changed = 1;
}
}
detect_address_change(ifp, 0, __PRETTY_FUNCTION__);
+ if (ifc->address->family != AF_INET)
+ return;
+
if (PIM_IF_TEST_IGMP(pim_ifp->options)) {
struct igmp_sock *igmp;
/* lookup IGMP socket */
igmp = pim_igmp_sock_lookup_ifaddr(pim_ifp->igmp_socket_list,
- ifaddr);
+ ifaddr);
if (!igmp) {
/* if addr new, add IGMP socket */
pim_igmp_sock_add(pim_ifp->igmp_socket_list, ifaddr, ifp);
}
+
+ /* Replay Static IGMP groups */
+ if (pim_ifp->igmp_join_list)
+ {
+ struct listnode *node;
+ struct listnode *nextnode;
+ struct igmp_join *ij;
+ int join_fd;
+
+ for (ALL_LIST_ELEMENTS (pim_ifp->igmp_join_list, node, nextnode, ij))
+ {
+ /* Close socket and reopen with Source and Group */
+ close(ij->sock_fd);
+ join_fd = igmp_join_sock(ifp->name, ifp->ifindex, ij->group_addr, ij->source_addr);
+ if (join_fd < 0)
+ {
+ char group_str[INET_ADDRSTRLEN];
+ char source_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<grp?>", ij->group_addr, group_str, sizeof(group_str));
+ pim_inet4_dump("<src?>", ij->source_addr, source_str, sizeof(source_str));
+ zlog_warn("%s: igmp_join_sock() failure for IGMP group %s source %s on interface %s",
+ __PRETTY_FUNCTION__,
+ group_str, source_str, ifp->name);
+ /* warning only */
+ }
+ else
+ ij->sock_fd = join_fd;
+ }
+ }
} /* igmp */
if (PIM_IF_TEST_PIM(pim_ifp->options))
ifp = ifc->ifp;
zassert(ifp);
+ if (ifc->address->family != AF_INET)
+ return;
+
if (PIM_DEBUG_ZEBRA) {
char buf[BUFSIZ];
prefix2str(ifc->address, buf, BUFSIZ);
zlog_debug("%s: %s ifindex=%d disconnected IP address %s %s",
- __PRETTY_FUNCTION__,
- ifp->name, ifp->ifindex, buf,
- CHECK_FLAG(ifc->flags, ZEBRA_IFA_SECONDARY) ?
- "secondary" : "primary");
+ __PRETTY_FUNCTION__,
+ ifp->name, ifp->ifindex, buf,
+ CHECK_FLAG(ifc->flags, ZEBRA_IFA_SECONDARY) ?
+ "secondary" : "primary");
}
detect_address_change(ifp, force_prim_as_any, __PRETTY_FUNCTION__);
struct prefix *p = ifc->address;
if (p->family != AF_INET)
- {
- v6_addrs++;
- continue;
- }
-
- v4_addrs++;
+ v6_addrs++;
+ else
+ v4_addrs++;
pim_if_addr_add(ifc);
}
struct listnode *neighnode;
struct pim_neighbor *neigh;
struct pim_interface *pim_ifp;
+ struct prefix p;
zassert(ifp);
return 0;
}
+ p.family = AF_INET;
+ p.u.prefix4 = addr;
+ p.prefixlen = IPV4_MAX_PREFIXLEN;
+
for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_neighbor_list, neighnode, neigh)) {
/* primary address ? */
return neigh;
/* secondary address ? */
- if (pim_neighbor_find_secondary(neigh, addr))
+ if (pim_neighbor_find_secondary(neigh, &p))
return neigh;
}
struct connected *c;
struct prefix p;
+ if (!ifp)
+ return 0;
+
p.family = AF_INET;
p.u.prefix4 = src;
p.prefixlen = IPV4_MAX_BITLEN;
}
for (ALL_LIST_ELEMENTS_RO(pim_ifp->sec_addr_list, node, sec_addr)) {
- if (sec_addr->addr.s_addr == rp_info->rp.rpf_addr.u.prefix4.s_addr) {
+ if (prefix_same(&sec_addr->addr, &rp_info->rp.rpf_addr)) {
return 1;
}
}
int
pim_rp_new (const char *rp, const char *group_range, const char *plist)
{
- int result;
+ int result = 0;
struct rp_info *rp_info;
struct rp_info *rp_all;
struct prefix group_all;
char buf1[PREFIX2STR_BUFFER];
prefix2str (&nht_p, buf, sizeof (buf));
prefix2str (&rp_info->group, buf1, sizeof (buf1));
- zlog_debug ("%s: NHT Register RP addr %s grp %s with Zebra ",
+ zlog_debug ("%s: NHT Register RP addr %s grp %s with Zebra",
__PRETTY_FUNCTION__, buf, buf1);
}
memset (&pnc, 0, sizeof (struct pim_nexthop_cache));
char buf1[PREFIX2STR_BUFFER];
prefix2str (&nht_p, buf, sizeof (buf));
prefix2str (&g, buf1, sizeof (buf1));
- zlog_debug ("%s: NHT nexthop cache not found for RP %s grp %s",
+ zlog_debug ("%s: Nexthop cache not found for RP %s grp %s register with Zebra",
__PRETTY_FUNCTION__, buf, buf1);
}
pim_rpf_set_refresh_time ();
{
if (nh_node->gate.ipv4.s_addr == 0)
{
- nbr =
- pim_neighbor_find_if (if_lookup_by_index
+ nbr = pim_neighbor_find_if (if_lookup_by_index
(nh_node->ifindex, VRF_DEFAULT));
if (nbr)
{
{
char str[PREFIX_STRLEN];
char str1[INET_ADDRSTRLEN];
+ struct interface *ifp1 = if_lookup_by_index(nh_node->ifindex,
+ VRF_DEFAULT);
pim_inet4_dump ("<nht_nbr?>", nbr->source_addr,
str1, sizeof (str1));
pim_addr_dump ("<nht_addr?>", &nht_p, str,
sizeof (str));
- zlog_debug
- ("%s: addr %s new nexthop addr %s ifindex %d ",
+ zlog_debug ("%s: addr %s new nexthop addr %s interface %s",
__PRETTY_FUNCTION__, str, str1,
- nh_node->ifindex);
+ ifp1->name);
}
}
}
writes += pim_msdp_config_write (vty);
+ if (!pimg->send_v6_secondary)
+ {
+ vty_out (vty, "no ip pim send-v6-secondary%s", VTY_NEWLINE);
+ ++writes;
+ }
+
writes += pim_rp_config_write (vty);
if (qpim_register_suppress_time != PIM_REGISTER_SUPPRESSION_TIME_DEFAULT)
VTY_NEWLINE);
++writes;
}
-
+ if (qpim_ecmp_rebalance_enable)
+ {
+ vty_out (vty, "ip pim ecmp rebalance%s", VTY_NEWLINE);
+ ++writes;
+ }
+ else if (qpim_ecmp_enable)
+ {
+ vty_out (vty, "ip pim ecmp%s", VTY_NEWLINE);
+ ++writes;
+ }
if (qpim_ssmpingd_list) {
struct listnode *node;
struct ssmpingd_sock *ss;
static struct zclient *zclient = NULL;
- static int fib_lookup_if_vif_index(struct in_addr addr);
/* Router-id update message from zebra. */
static int pim_router_id_update_zebra(int command, struct zclient *zclient,
#endif
}
- if (p->family != AF_INET)
- {
- struct listnode *cnode;
- struct connected *conn;
- int v4addrs = 0;
-
- for (ALL_LIST_ELEMENTS_RO (c->ifp->connected, cnode, conn))
- {
- if (conn->address->family == AF_INET)
- v4addrs++;
- }
- if (!v4addrs && pim_ifp)
- {
- pim_ifp->primary_address = pim_find_primary_addr (c->ifp);
- pim_if_addr_add_all (c->ifp);
- pim_if_add_vif (c->ifp);
- }
- return 0;
- }
-
if (!CHECK_FLAG(c->flags, ZEBRA_IFA_SECONDARY)) {
/* trying to add primary address */
struct in_addr primary_addr = pim_find_primary_addr(c->ifp);
- if (primary_addr.s_addr != p->u.prefix4.s_addr) {
+ if (p->family != AF_INET || primary_addr.s_addr != p->u.prefix4.s_addr) {
if (PIM_DEBUG_ZEBRA) {
/* but we had a primary address already */
if (in_vif_index)
input_iface_vif_index = in_vif_index;
else
- input_iface_vif_index = fib_lookup_if_vif_index (vif_source);
+ {
+ struct prefix src, grp;
+
+ src.family = AF_INET;
+ src.prefixlen = IPV4_MAX_BITLEN;
+ src.u.prefix4 = vif_source;
+ grp.family = AF_INET;
+ grp.prefixlen = IPV4_MAX_BITLEN;
+ grp.u.prefix4 = c_oil->oil.mfcc_mcastgrp;
+
+ if (PIM_DEBUG_ZEBRA)
+ {
+ char source_str[INET_ADDRSTRLEN];
+ char group_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<source?>", c_oil->oil.mfcc_origin, source_str, sizeof(source_str));
+ pim_inet4_dump("<group?>", c_oil->oil.mfcc_mcastgrp, group_str, sizeof(group_str));
+ zlog_debug ("%s: channel_oil (%s, %s) upstream info is not present.",
+ __PRETTY_FUNCTION__, source_str, group_str);
+ }
+ input_iface_vif_index = pim_ecmp_fib_lookup_if_vif_index(vif_source, &src, &grp);
+ }
+
if (input_iface_vif_index < 1)
{
if (PIM_DEBUG_ZEBRA)
struct listnode *node;
struct listnode *nextnode;
struct channel_oil *c_oil;
+ ifindex_t ifindex;
+ int vif_index = 0;
qpim_scan_oil_last = pim_time_monotonic_sec();
++qpim_scan_oil_events;
for (ALL_LIST_ELEMENTS(pim_channel_oil_list, node, nextnode, c_oil))
- pim_scan_individual_oil (c_oil, 0);
+ {
+ if (c_oil->up && c_oil->up->rpf.source_nexthop.interface)
+ {
+ ifindex = c_oil->up->rpf.source_nexthop.interface->ifindex;
+ vif_index = pim_if_find_vifindex_by_ifindex (ifindex);
+ /* Pass Current selected NH vif index to mroute download */
+ if (vif_index)
+ pim_scan_individual_oil (c_oil, vif_index);
+ }
+ else
+ pim_scan_individual_oil (c_oil, 0);
+ }
}
static int on_rpf_cache_refresh(struct thread *t)
igmp_source_forward_stop (source);
}
- static int fib_lookup_if_vif_index(struct in_addr addr)
- {
- struct pim_zlookup_nexthop nexthop_tab[MULTIPATH_NUM];
- int num_ifindex;
- int vif_index;
- ifindex_t first_ifindex;
-
- num_ifindex = zclient_lookup_nexthop(nexthop_tab,
- MULTIPATH_NUM, addr,
- PIM_NEXTHOP_LOOKUP_MAX);
- if (num_ifindex < 1) {
- if (PIM_DEBUG_ZEBRA)
- {
- char addr_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<addr?>", addr, addr_str, sizeof(addr_str));
- zlog_debug("%s %s: could not find nexthop ifindex for address %s",
- __FILE__, __PRETTY_FUNCTION__,
- addr_str);
- }
- return -1;
- }
-
- first_ifindex = nexthop_tab[0].ifindex;
-
- if (num_ifindex > 1) {
- if (PIM_DEBUG_ZEBRA)
- {
- char addr_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<addr?>", addr, addr_str, sizeof(addr_str));
- zlog_debug("%s %s: FIXME ignoring multiple nexthop ifindex'es num_ifindex=%d for address %s (using only ifindex=%d)",
- __FILE__, __PRETTY_FUNCTION__,
- num_ifindex, addr_str, first_ifindex);
- }
- /* debug warning only, do not return */
- }
-
- if (PIM_DEBUG_ZEBRA) {
- char addr_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<ifaddr?>", addr, addr_str, sizeof(addr_str));
- zlog_debug("%s %s: found nexthop ifindex=%d (interface %s) for address %s",
- __FILE__, __PRETTY_FUNCTION__,
- first_ifindex, ifindex2ifname(first_ifindex, VRF_DEFAULT), addr_str);
- }
-
- vif_index = pim_if_find_vifindex_by_ifindex(first_ifindex);
-
- if (vif_index < 0) {
- if (PIM_DEBUG_ZEBRA)
- {
- char addr_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<addr?>", addr, addr_str, sizeof(addr_str));
- zlog_debug("%s %s: low vif_index=%d < 1 nexthop for address %s",
- __FILE__, __PRETTY_FUNCTION__,
- vif_index, addr_str);
- }
- return -2;
- }
-
- return vif_index;
- }
-
static void
igmp_source_forward_reevaluate_one(struct igmp_source *source)
{
int ret = 0;
struct pim_nexthop_cache out_pnc;
struct pim_nexthop nexthop;
+ struct pim_upstream *up = NULL;
if (!pim_rp_set_upstream_addr (&vif_source, source->source_addr, sg.grp))
return;
nht_p.u.prefix4 = vif_source;
memset (&out_pnc, 0, sizeof (struct pim_nexthop_cache));
+ src.family = AF_INET;
+ src.prefixlen = IPV4_MAX_BITLEN;
+ src.u.prefix4 = vif_source; //RP or Src address
+ grp.family = AF_INET;
+ grp.prefixlen = IPV4_MAX_BITLEN;
+ grp.u.prefix4 = sg.grp;
+
if ((ret = pim_find_or_track_nexthop (&nht_p, NULL, NULL, &out_pnc)) == 1)
{
if (out_pnc.nexthop_num)
{
- src.family = AF_INET;
- src.prefixlen = IPV4_MAX_BITLEN;
- src.u.prefix4 = vif_source; //RP or Src address
- grp.family = AF_INET;
- grp.prefixlen = IPV4_MAX_BITLEN;
- grp.u.prefix4 = sg.grp;
- memset (&nexthop, 0, sizeof (nexthop));
+ up = pim_upstream_find (&sg);
+ memset (&nexthop, 0, sizeof (struct pim_nexthop));
+ if (up)
+ memcpy (&nexthop, &up->rpf.source_nexthop, sizeof (struct pim_nexthop));
//Compute PIM RPF using Cached nexthop
- pim_ecmp_nexthop_search (&out_pnc, &nexthop,
- &src, &grp, 0);
+ pim_ecmp_nexthop_search (&out_pnc, &nexthop, &src, &grp, 0);
if (nexthop.interface)
input_iface_vif_index = pim_if_find_vifindex_by_ifindex (nexthop.interface->ifindex);
}
}
}
else
- input_iface_vif_index = fib_lookup_if_vif_index(vif_source);
+ input_iface_vif_index = pim_ecmp_fib_lookup_if_vif_index(vif_source, &src, &grp);
if (PIM_DEBUG_ZEBRA)
{
struct prefix nht_p, src, grp;
int ret = 0;
struct pim_nexthop_cache out_pnc;
- struct pim_nexthop nexthop;
/* Register addr with Zebra NHT */
nht_p.family = AF_INET;
grp.u.prefix4 = up->sg.grp;
memset (&out_pnc, 0, sizeof (struct pim_nexthop_cache));
- if ((ret =
- pim_find_or_track_nexthop (&nht_p, NULL, NULL, &out_pnc)) == 1)
+ if ((ret = pim_find_or_track_nexthop (&nht_p, NULL, NULL, &out_pnc)) == 1)
{
if (out_pnc.nexthop_num)
{
grp.family = AF_INET;
grp.prefixlen = IPV4_MAX_BITLEN;
grp.u.prefix4 = up->sg.grp;
- memset (&nexthop, 0, sizeof (nexthop));
//Compute PIM RPF using Cached nexthop
- pim_ecmp_nexthop_search (&out_pnc, &nexthop, &src, &grp, 0);
- input_iface_vif_index =
- pim_if_find_vifindex_by_ifindex (nexthop.interface->ifindex);
+ if (pim_ecmp_nexthop_search (&out_pnc, &up->rpf.source_nexthop, &src, &grp, 0) == 0)
+ input_iface_vif_index = pim_if_find_vifindex_by_ifindex (up->rpf.source_nexthop.interface->ifindex);
+ else
+ {
+ if (PIM_DEBUG_TRACE)
+ zlog_debug ("%s: Nexthop selection failed for %s ", __PRETTY_FUNCTION__, up->sg_str);
+ }
}
else
{
}
}
else
- input_iface_vif_index = fib_lookup_if_vif_index (up->upstream_addr);
+ input_iface_vif_index = pim_ecmp_fib_lookup_if_vif_index(up->upstream_addr, &src, &grp);
if (input_iface_vif_index < 1)
{
}
if (PIM_DEBUG_TRACE)
{
- zlog_debug ("%s: NHT entry %s update channel_oil vif_index %d ",
- __PRETTY_FUNCTION__, up->sg_str, input_iface_vif_index);
+ struct interface *in_intf = pim_if_find_by_vif_index (input_iface_vif_index);
+ zlog_debug ("%s: Update channel_oil IIF %s VIFI %d entry %s ",
+ __PRETTY_FUNCTION__, in_intf ? in_intf->name : "NIL",
+ input_iface_vif_index, up->sg_str);
}
up->channel_oil = pim_channel_oil_add (&up->sg, input_iface_vif_index);
if (!up->channel_oil)
for setting ifindex to IFINDEX_INTERNAL after processing the
interface deletion message. */
ifp->ifindex = IFINDEX_INTERNAL;
+ ifp->node = NULL;
}
/* VRF change for an interface */
static void
link_param_cmd_unset (struct interface *ifp, uint32_t type)
{
+ if (ifp->link_params == NULL)
+ return;
/* Unset field */
UNSET_PARAM(ifp->link_params, type);