/* Prepend as1 to as2. as2 should be uninterned aspath. */
struct aspath *aspath_prepend(struct aspath *as1, struct aspath *as2)
{
- struct assegment *seg1;
- struct assegment *seg2;
+ struct assegment *as1segtail;
+ struct assegment *as2segtail;
+ struct assegment *as2seghead;
if (!as1 || !as2)
return NULL;
- seg1 = as1->segments;
- seg2 = as2->segments;
-
/* If as2 is empty, only need to dupe as1's chain onto as2 */
- if (seg2 == NULL) {
+ if (as2->segments == NULL) {
as2->segments = assegment_dup_all(as1->segments);
aspath_str_update(as2, false);
return as2;
}
/* If as1 is empty AS, no prepending to do. */
- if (seg1 == NULL)
+ if (as1->segments == NULL)
return as2;
/* find the tail as1's segment chain. */
- while (seg1 && seg1->next)
- seg1 = seg1->next;
+ as1segtail = as1->segments;
+ while (as1segtail && as1segtail->next)
+ as1segtail = as1segtail->next;
/* Delete any AS_CONFED_SEQUENCE segment from as2. */
- if (seg1->type == AS_SEQUENCE && seg2->type == AS_CONFED_SEQUENCE)
+ if (as1segtail->type == AS_SEQUENCE
+ && as2->segments->type == AS_CONFED_SEQUENCE)
as2 = aspath_delete_confed_seq(as2);
+ if (!as2->segments) {
+ as2->segments = assegment_dup_all(as1->segments);
+ aspath_str_update(as2, false);
+ return as2;
+ }
+
/* Compare last segment type of as1 and first segment type of as2. */
- if (seg1->type != seg2->type)
+ if (as1segtail->type != as2->segments->type)
return aspath_merge(as1, as2);
- if (seg1->type == AS_SEQUENCE) {
+ if (as1segtail->type == AS_SEQUENCE) {
/* We have two chains of segments, as1->segments and seg2,
* and we have to attach them together, merging the attaching
* segments together into one.
* 3. attach chain after seg2
*/
+ /* save as2 head */
+ as2seghead = as2->segments;
+
/* dupe as1 onto as2's head */
- seg1 = as2->segments = assegment_dup_all(as1->segments);
+ as2segtail = as2->segments = assegment_dup_all(as1->segments);
- /* refind the tail of as2, reusing seg1 */
- while (seg1 && seg1->next)
- seg1 = seg1->next;
+ /* refind the tail of as2 */
+ while (as2segtail && as2segtail->next)
+ as2segtail = as2segtail->next;
/* merge the old head, seg2, into tail, seg1 */
- seg1 = assegment_append_asns(seg1, seg2->as, seg2->length);
+ assegment_append_asns(as2segtail, as2seghead->as,
+ as2seghead->length);
- /* bypass the merged seg2, and attach any chain after it to
- * chain descending from as2's head
+ /*
+ * bypass the merged seg2, and attach any chain after it
+ * to chain descending from as2's head
*/
- seg1->next = seg2->next;
+ as2segtail->next = as2seghead->next;
- /* seg2 is now referenceless and useless*/
- assegment_free(seg2);
+ /* as2->segments is now referenceless and useless */
+ assegment_free(as2seghead);
/* we've now prepended as1's segment chain to as2, merging
* the inbetween AS_SEQUENCE of seg2 in the process
}
$str =~ s/ $//;
push @lines, $str . "\\n\" \\\n";
- push @lines, " \" > - selected route, * - FIB route, q - queued route, f - failed route\\n\\n\"";
+ push @lines, " \" > - selected route, * - FIB route, q - queued route, r - rejected route\\n\\n\"";
return join("", @lines);
}
#include "pim_bfd.h"
#include "bfd.h"
+#ifndef VTYSH_EXTRACT_PL
+#include "pimd/pim_cmd_clippy.c"
+#endif
+
static struct cmd_node interface_node = {
INTERFACE_NODE, "%s(config-if)# ", 1 /* vtysh ? yes */
};
return 1;
}
+DEFPY_HIDDEN (interface_ip_pim_activeactive,
+ interface_ip_pim_activeactive_cmd,
+ "[no$no] ip pim active-active",
+ NO_STR
+ IP_STR
+ PIM_STR
+ "Mark interface as Active-Active for MLAG operations, Hidden because not finished yet\n")
+{
+ VTY_DECLVAR_CONTEXT(interface, ifp);
+ struct pim_interface *pim_ifp;
+
+ if (!no && !pim_cmd_interface_add(ifp)) {
+ vty_out(vty, "Could not enable PIM SM active-active on interface\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+
+ pim_ifp = ifp->info;
+ if (no)
+ pim_ifp->activeactive = false;
+ else
+ pim_ifp->activeactive = true;
+
+ return CMD_SUCCESS;
+}
+
DEFUN_HIDDEN (interface_ip_pim_ssm,
interface_ip_pim_ssm_cmd,
"ip pim ssm",
&interface_ip_igmp_query_max_response_time_dsec_cmd);
install_element(INTERFACE_NODE,
&interface_no_ip_igmp_query_max_response_time_dsec_cmd);
+ install_element(INTERFACE_NODE, &interface_ip_pim_activeactive_cmd);
install_element(INTERFACE_NODE, &interface_ip_pim_ssm_cmd);
install_element(INTERFACE_NODE, &interface_no_ip_pim_ssm_cmd);
install_element(INTERFACE_NODE, &interface_ip_pim_sm_cmd);
pim_ifp->sec_addr_list->cmp =
(int (*)(void *, void *))pim_sec_addr_comp;
+ pim_ifp->activeactive = false;
+
RB_INIT(pim_ifchannel_rb, &pim_ifp->ifchannel_rb);
ifp->info = pim_ifp;
/* boundary prefix-list */
char *boundary_oil_plist;
+ /* Turn on Active-Active for this interface */
+ bool activeactive;
+
int64_t pim_ifstat_start; /* start timestamp for stats */
uint32_t pim_ifstat_hello_sent;
uint32_t pim_ifstat_hello_sendfail;
}
}
+ if (pim_ifp->activeactive)
+ vty_out(vty, " ip pim active-active\n");
+
/* boundary */
if (pim_ifp->boundary_oil_plist) {
vty_out(vty,
pimd/mtracebis_routeget.h \
# end
+pimd/pim_cmd_clippy.c: $(CLIPPY_DEPS)
+pimd/pim_cmd.$(OBJEXT): pimd/pim_cmd_clippy.c
+
pimd_pimd_LDADD = pimd/libpim.a lib/libfrr.la $(LIBCAP)
pimd_pimd_SOURCES = pimd/pim_main.c
#include "command.h"
#include "debug.h"
+#ifndef VTYSH_EXTRACT_PL
+#include "zebra/debug_clippy.c"
+#endif
+
/* For debug statement. */
unsigned long zebra_debug_event;
unsigned long zebra_debug_packet;
unsigned long zebra_debug_vxlan;
unsigned long zebra_debug_pw;
unsigned long zebra_debug_dplane;
+unsigned long zebra_debug_mlag;
DEFINE_HOOK(zebra_debug_show_debugging, (struct vty *vty), (vty));
vty_out(vty, " Zebra detailed dataplane debugging is on\n");
else if (IS_ZEBRA_DEBUG_DPLANE)
vty_out(vty, " Zebra dataplane debugging is on\n");
+ if (IS_ZEBRA_DEBUG_MLAG)
+ vty_out(vty, " Zebra mlag debugging is on\n");
hook_call(zebra_debug_show_debugging, vty);
return CMD_SUCCESS;
return CMD_SUCCESS;
}
+DEFPY (debug_zebra_mlag,
+ debug_zebra_mlag_cmd,
+ "[no$no] debug zebra mlag",
+ NO_STR
+ DEBUG_STR
+ "Zebra configuration\n"
+ "Debug option set for mlag events\n")
+{
+ if (no)
+ UNSET_FLAG(zebra_debug_mlag, ZEBRA_DEBUG_MLAG);
+ else
+ SET_FLAG(zebra_debug_mlag, ZEBRA_DEBUG_MLAG);
+ return CMD_SUCCESS;
+}
+
DEFUN (no_debug_zebra_events,
no_debug_zebra_events_cmd,
"no debug zebra events",
zebra_debug_vxlan = 0;
zebra_debug_pw = 0;
zebra_debug_dplane = 0;
+ zebra_debug_mlag = 0;
install_node(&debug_node, config_write_debug);
install_element(ENABLE_NODE, &debug_zebra_rib_cmd);
install_element(ENABLE_NODE, &debug_zebra_fpm_cmd);
install_element(ENABLE_NODE, &debug_zebra_dplane_cmd);
+ install_element(ENABLE_NODE, &debug_zebra_mlag_cmd);
install_element(ENABLE_NODE, &no_debug_zebra_events_cmd);
install_element(ENABLE_NODE, &no_debug_zebra_nht_cmd);
install_element(ENABLE_NODE, &no_debug_zebra_mpls_cmd);
#define ZEBRA_DEBUG_DPLANE 0x01
#define ZEBRA_DEBUG_DPLANE_DETAILED 0x02
+#define ZEBRA_DEBUG_MLAG 0x01
+
/* Debug related macro. */
#define IS_ZEBRA_DEBUG_EVENT (zebra_debug_event & ZEBRA_DEBUG_EVENT)
#define IS_ZEBRA_DEBUG_DPLANE_DETAIL \
(zebra_debug_dplane & ZEBRA_DEBUG_DPLANE_DETAILED)
+#define IS_ZEBRA_DEBUG_MLAG (zebra_debug_mlag & ZEBRA_DEBUG_MLAG)
+
extern unsigned long zebra_debug_event;
extern unsigned long zebra_debug_packet;
extern unsigned long zebra_debug_kernel;
extern unsigned long zebra_debug_vxlan;
extern unsigned long zebra_debug_pw;
extern unsigned long zebra_debug_dplane;
+extern unsigned long zebra_debug_mlag;
extern void zebra_debug_init(void);
#include "zebra/interface.h"
#include "zebra/rib.h"
#include "zebra/rt.h"
-#include "zebra/zserv.h"
+#include "zebra/zebra_router.h"
#include "zebra/redistribute.h"
#include "zebra/debug.h"
#include "zebra/irdp.h"
* of seconds and ask again. Hopefully it's all settled
* down upon startup.
*/
- thread_add_timer(zebrad.master, if_zebra_speed_update, ifp, 15,
+ thread_add_timer(zrouter.master, if_zebra_speed_update, ifp, 15,
&zebra_if->speed_update);
return 0;
}
#include "zebra/interface.h"
#include "zebra/rtadv.h"
#include "zebra/rib.h"
-#include "zebra/zserv.h"
+#include "zebra/zebra_router.h"
#include "zebra/redistribute.h"
#include "zebra/irdp.h"
#include "zebra/zebra_errors.h"
timer);
irdp->t_advertise = NULL;
- thread_add_timer(zebrad.master, irdp_send_thread, ifp, timer,
+ thread_add_timer(zrouter.master, irdp_send_thread, ifp, timer,
&irdp->t_advertise);
}
#include "zebra/interface.h"
#include "zebra/rtadv.h"
#include "zebra/rib.h"
-#include "zebra/zserv.h"
+#include "zebra/zebra_router.h"
#include "zebra/redistribute.h"
#include "zebra/irdp.h"
#include "zebra/zebra_errors.h"
};
t_irdp_raw = NULL;
- thread_add_read(zebrad.master, irdp_read_raw, NULL, sock, &t_irdp_raw);
+ thread_add_read(zrouter.master, irdp_read_raw, NULL, sock, &t_irdp_raw);
return sock;
}
timer);
irdp->t_advertise = NULL;
- thread_add_timer(zebrad.master, irdp_send_thread, ifp, timer,
+ thread_add_timer(zrouter.master, irdp_send_thread, ifp, timer,
&irdp->t_advertise);
return 0;
}
timer = (random() % MAX_RESPONSE_DELAY) + 1;
irdp->t_advertise = NULL;
- thread_add_timer(zebrad.master, irdp_send_thread, ifp, timer,
+ thread_add_timer(zrouter.master, irdp_send_thread, ifp, timer,
&irdp->t_advertise);
}
#include "zebra/interface.h"
#include "zebra/rtadv.h"
#include "zebra/rib.h"
-#include "zebra/zserv.h"
+#include "zebra/zebra_router.h"
#include "zebra/redistribute.h"
#include "zebra/irdp.h"
#include "zebra/zebra_errors.h"
int irdp_sock = THREAD_FD(r);
t_irdp_raw = NULL;
- thread_add_read(zebrad.master, irdp_read_raw, NULL, irdp_sock,
+ thread_add_read(zrouter.master, irdp_read_raw, NULL, irdp_sock,
&t_irdp_raw);
ret = irdp_recvmsg(irdp_sock, (uint8_t *)buf, IRDP_RX_BUF, &ifindex);
#include "mpls.h"
#include "lib_errors.h"
-#include "zebra/zserv.h"
+//#include "zebra/zserv.h"
+#include "zebra/zebra_router.h"
#include "zebra/zebra_ns.h"
#include "zebra/zebra_vrf.h"
#include "zebra/rt.h"
netlink_parse_info(netlink_information_fetch, &zns->netlink, &dp_info,
5, 0);
zns->t_netlink = NULL;
- thread_add_read(zebrad.master, kernel_read, zns, zns->netlink.sock,
+ thread_add_read(zrouter.master, kernel_read, zns, zns->netlink.sock,
&zns->t_netlink);
return 0;
zns->t_netlink = NULL;
- thread_add_read(zebrad.master, kernel_read, zns,
+ thread_add_read(zrouter.master, kernel_read, zns,
zns->netlink.sock, &zns->t_netlink);
rt_netlink_init();
#include "zebra/rt.h"
#include "zebra/interface.h"
-#include "zebra/zserv.h"
+#include "zebra/zebra_router.h"
#include "zebra/debug.h"
#include "zebra/kernel_socket.h"
#include "zebra/rib.h"
return 0;
}
- thread_add_read(zebrad.master, kernel_read, NULL, sock, NULL);
+ thread_add_read(zrouter.master, kernel_read, NULL, sock, NULL);
if (IS_ZEBRA_DEBUG_KERNEL)
rtmsg_debug(&buf.r.rtm);
zlog_warn ("Can't set O_NONBLOCK to routing socket");*/
/* kernel_read needs rewrite. */
- thread_add_read(zebrad.master, kernel_read, NULL, routing_sock, NULL);
+ thread_add_read(zrouter.master, kernel_read, NULL, routing_sock, NULL);
}
/* Exported interface function. This function simply calls
#include "lib/zclient.h"
#include "lib/libfrr.h"
-#include "zebra/zserv.h"
+//#include "zebra/zserv.h"
+#include "zebra/zebra_router.h"
#include "zebra/label_manager.h"
#include "zebra/zebra_errors.h"
if (zclient_socket_connect(zclient) < 0) {
flog_err(EC_ZEBRA_LM_CLIENT_CONNECTION_FAILED,
"Error connecting synchronous zclient!");
- thread_add_timer(zebrad.master, lm_zclient_connect, zclient,
+ thread_add_timer(zrouter.master, lm_zclient_connect, zclient,
CONNECTION_DELAY, &zclient->t_connect);
return -1;
}
lm_zserv_path);
/* Set default values. */
- zclient = zclient_new(zebrad.master, &zclient_options_default);
+ zclient = zclient_new(zrouter.master, &zclient_options_default);
zclient->privs = &zserv_privs;
zclient->sock = -1;
zclient->t_connect = NULL;
#define ZEBRA_PTM_SUPPORT
-/* Zebra instance */
-struct zebra_t zebrad = {
- .rtm_table_default = 0,
- .packets_to_process = ZEBRA_ZAPI_PACKETS_TO_PROCESS,
-};
-
/* process id. */
pid_t pid;
zebra_dplane_pre_finish();
- for (ALL_LIST_ELEMENTS(zebrad.client_list, ln, nn, client))
+ for (ALL_LIST_ELEMENTS(zrouter.client_list, ln, nn, client))
zserv_close_client(client);
- list_delete_all_node(zebrad.client_list);
+ list_delete_all_node(zrouter.client_list);
zebra_ptm_finish();
if (retain_mode)
if (zvrf)
SET_FLAG(zvrf->flags, ZEBRA_VRF_RETAIN);
}
- if (zebrad.lsp_process_q)
- work_queue_free_and_null(&zebrad.lsp_process_q);
+ if (zrouter.lsp_process_q)
+ work_queue_free_and_null(&zrouter.lsp_process_q);
vrf_terminate();
ns_walk_func(zebra_ns_early_shutdown);
prefix_list_reset();
route_map_finish();
- list_delete(&zebrad.client_list);
+ list_delete(&zrouter.client_list);
/* Indicate that all new dplane work has been enqueued. When that
* work is complete, the dataplane will enqueue an event
/* Stop dplane thread and finish any cleanup */
zebra_dplane_shutdown();
- work_queue_free_and_null(&zebrad.ribq);
- meta_queue_free(zebrad.mq);
-
zebra_router_terminate();
frr_fini();
}
}
- zebrad.master = frr_init();
+ zrouter.master = frr_init();
/* Initialize pthread library */
frr_pthread_init();
#endif /* HANDLE_NETLINK_FUZZING */
- frr_run(zebrad.master);
+ frr_run(zrouter.master);
/* Not reached... */
return 0;
#include "srcdest_table.h"
#include "zebra/rib.h"
-#include "zebra/zserv.h"
+#include "zebra/zebra_router.h"
#include "zebra/zebra_ns.h"
#include "zebra/zebra_vrf.h"
#include "zebra/zebra_routemap.h"
return;
}
- for (ALL_LIST_ELEMENTS(zebrad.client_list, node, nnode, client)) {
+ for (ALL_LIST_ELEMENTS(zrouter.client_list, node, nnode, client)) {
send_redistribute = 0;
if (is_default_prefix(p)
return;
}
- for (ALL_LIST_ELEMENTS(zebrad.client_list, node, nnode, client)) {
+ for (ALL_LIST_ELEMENTS(zrouter.client_list, node, nnode, client)) {
if ((is_default_prefix(p)
&& vrf_bitmap_check(client->redist_default[afi],
re->vrf_id))
ifp->name, ifp->vrf_id);
if (ifp->ptm_status || !ifp->ptm_enable) {
- for (ALL_LIST_ELEMENTS(zebrad.client_list, node, nnode, client))
+ for (ALL_LIST_ELEMENTS(zrouter.client_list, node, nnode,
+ client))
if (vrf_bitmap_check(client->ifinfo, ifp->vrf_id)) {
zsend_interface_update(ZEBRA_INTERFACE_UP,
client, ifp);
zlog_debug("MESSAGE: ZEBRA_INTERFACE_DOWN %s(%u)",
ifp->name, ifp->vrf_id);
- for (ALL_LIST_ELEMENTS(zebrad.client_list, node, nnode, client)) {
+ for (ALL_LIST_ELEMENTS(zrouter.client_list, node, nnode, client)) {
zsend_interface_update(ZEBRA_INTERFACE_DOWN, client, ifp);
}
}
zlog_debug("MESSAGE: ZEBRA_INTERFACE_ADD %s(%u)", ifp->name,
ifp->vrf_id);
- for (ALL_LIST_ELEMENTS(zebrad.client_list, node, nnode, client))
+ for (ALL_LIST_ELEMENTS(zrouter.client_list, node, nnode, client))
if (vrf_bitmap_check(client->ifinfo, ifp->vrf_id)) {
client->ifadd_cnt++;
zsend_interface_add(client, ifp);
zlog_debug("MESSAGE: ZEBRA_INTERFACE_DELETE %s(%u)",
ifp->name, ifp->vrf_id);
- for (ALL_LIST_ELEMENTS(zebrad.client_list, node, nnode, client)) {
+ for (ALL_LIST_ELEMENTS(zrouter.client_list, node, nnode, client)) {
client->ifdel_cnt++;
zsend_interface_delete(client, ifp);
}
router_id_add_address(ifc);
- for (ALL_LIST_ELEMENTS(zebrad.client_list, node, nnode, client))
+ for (ALL_LIST_ELEMENTS(zrouter.client_list, node, nnode, client))
if (CHECK_FLAG(ifc->conf, ZEBRA_IFC_REAL)) {
client->connected_rt_add_cnt++;
zsend_interface_address(ZEBRA_INTERFACE_ADDRESS_ADD,
router_id_del_address(ifc);
- for (ALL_LIST_ELEMENTS(zebrad.client_list, node, nnode, client))
+ for (ALL_LIST_ELEMENTS(zrouter.client_list, node, nnode, client))
if (CHECK_FLAG(ifc->conf, ZEBRA_IFC_REAL)) {
client->connected_rt_del_cnt++;
zsend_interface_address(ZEBRA_INTERFACE_ADDRESS_DELETE,
"MESSAGE: ZEBRA_INTERFACE_VRF_UPDATE/DEL %s VRF Id %u -> %u",
ifp->name, ifp->vrf_id, new_vrf_id);
- for (ALL_LIST_ELEMENTS(zebrad.client_list, node, nnode, client)) {
+ for (ALL_LIST_ELEMENTS(zrouter.client_list, node, nnode, client)) {
/* Need to delete if the client is not interested in the new
* VRF. */
zsend_interface_update(ZEBRA_INTERFACE_DOWN, client, ifp);
"MESSAGE: ZEBRA_INTERFACE_VRF_UPDATE/ADD %s VRF Id %u -> %u",
ifp->name, old_vrf_id, ifp->vrf_id);
- for (ALL_LIST_ELEMENTS(zebrad.client_list, node, nnode, client)) {
+ for (ALL_LIST_ELEMENTS(zrouter.client_list, node, nnode, client)) {
/* Need to add if the client is interested in the new VRF. */
client->ifadd_cnt++;
zsend_interface_add(client, ifp);
newre->flags = re->flags;
newre->metric = re->metric;
newre->mtu = re->mtu;
- newre->table = zebrad.rtm_table_default;
+ newre->table = zrouter.rtm_table_default;
newre->nexthop_num = 0;
newre->uptime = time(NULL);
newre->instance = re->table;
rib_delete(afi, SAFI_UNICAST, re->vrf_id, ZEBRA_ROUTE_TABLE, re->table,
re->flags, &p, NULL, re->ng.nexthop,
- zebrad.rtm_table_default, re->metric, re->distance, false);
+ zrouter.rtm_table_default, re->metric, re->distance, false);
return 0;
}
if (!is_zebra_valid_kernel_table(table_id)
|| ((table_id == RT_TABLE_MAIN)
- || (table_id == zebrad.rtm_table_default)))
+ || (table_id == zrouter.rtm_table_default)))
return (-1);
if (afi >= AFI_MAX)
zlog_debug("MESSAGE: ZEBRA_INTERFACE_LINK_PARAMS %s(%u)",
ifp->name, ifp->vrf_id);
- for (ALL_LIST_ELEMENTS(zebrad.client_list, node, nnode, client))
+ for (ALL_LIST_ELEMENTS(zrouter.client_list, node, nnode, client))
if (vrf_bitmap_check(client->ifinfo, ifp->vrf_id))
zsend_interface_link_params(client, ifp);
}
#include "rib.h"
#include "vrf.h"
-#include "zebra/zserv.h"
+#include "zebra/zebra_router.h"
#include "zebra/zapi_msg.h"
#include "zebra/zebra_vrf.h"
#include "zebra/router-id.h"
#include "zebra/redistribute.h"
-/* master zebra server structure */
-extern struct zebra_t zebrad;
-
static struct connected *router_id_find_node(struct list *l,
struct connected *ifc)
{
router_id_get(&p2, vrf_id);
- for (ALL_LIST_ELEMENTS_RO(zebrad.client_list, node, client))
+ for (ALL_LIST_ELEMENTS_RO(zrouter.client_list, node, client))
zsend_router_id_update(client, &p2, vrf_id);
}
if (prefix_same(&before, &after))
return;
- for (ALL_LIST_ELEMENTS_RO(zebrad.client_list, node, client))
+ for (ALL_LIST_ELEMENTS_RO(zrouter.client_list, node, client))
zsend_router_id_update(client, &after, zvrf_id(zvrf));
}
if (prefix_same(&before, &after))
return;
- for (ALL_LIST_ELEMENTS_RO(zebrad.client_list, node, client))
+ for (ALL_LIST_ELEMENTS_RO(zrouter.client_list, node, client))
zsend_router_id_update(client, &after, zvrf_id(zvrf));
}
if (nexthop->type != NEXTHOP_TYPE_BLACKHOLE)
addattr32(nlmsg, req_size, RTA_OIF, nexthop->ifindex);
- if (nexthop->type == NEXTHOP_TYPE_IFINDEX
- || nexthop->type == NEXTHOP_TYPE_IPV4_IFINDEX) {
+ if (nexthop->type == NEXTHOP_TYPE_IFINDEX) {
if (cmd == RTM_NEWROUTE) {
if (nexthop->rmap_src.ipv4.s_addr)
addattr_l(nlmsg, req_size, RTA_PREFSRC,
"nexthop via if %u(%u)",
routedesc, nexthop->ifindex, nexthop->vrf_id);
}
-
- if (nexthop->type == NEXTHOP_TYPE_IPV6_IFINDEX) {
- if (cmd == RTM_NEWROUTE) {
- if (!IN6_IS_ADDR_UNSPECIFIED(&nexthop->rmap_src.ipv6))
- addattr_l(nlmsg, req_size, RTA_PREFSRC,
- &nexthop->rmap_src.ipv6, bytelen);
- else if (!IN6_IS_ADDR_UNSPECIFIED(&nexthop->src.ipv6))
- addattr_l(nlmsg, req_size, RTA_PREFSRC,
- &nexthop->src.ipv6, bytelen);
- }
-
- if (IS_ZEBRA_DEBUG_KERNEL)
- zlog_debug(
- "netlink_route_multipath() (%s): "
- "nexthop via if %u(%u)",
- routedesc, nexthop->ifindex, nexthop->vrf_id);
- }
}
/* This function takes a nexthop as argument and
rtnh->rtnh_ifindex = nexthop->ifindex;
/* ifindex */
- if (nexthop->type == NEXTHOP_TYPE_IPV4_IFINDEX
- || nexthop->type == NEXTHOP_TYPE_IFINDEX) {
+ if (nexthop->type == NEXTHOP_TYPE_IFINDEX) {
if (nexthop->rmap_src.ipv4.s_addr)
*src = &nexthop->rmap_src;
else if (nexthop->src.ipv4.s_addr)
switch (event) {
case RTADV_START:
- thread_add_read(zebrad.master, rtadv_read, zns, val,
+ thread_add_read(zrouter.master, rtadv_read, zns, val,
&rtadv->ra_read);
- thread_add_event(zebrad.master, rtadv_timer, zns, 0,
+ thread_add_event(zrouter.master, rtadv_timer, zns, 0,
&rtadv->ra_timer);
break;
case RTADV_STOP:
}
break;
case RTADV_TIMER:
- thread_add_timer(zebrad.master, rtadv_timer, zns, val,
+ thread_add_timer(zrouter.master, rtadv_timer, zns, val,
&rtadv->ra_timer);
break;
case RTADV_TIMER_MSEC:
- thread_add_timer_msec(zebrad.master, rtadv_timer, zns, val,
+ thread_add_timer_msec(zrouter.master, rtadv_timer, zns, val,
&rtadv->ra_timer);
break;
case RTADV_READ:
- thread_add_read(zebrad.master, rtadv_read, zns, val,
+ thread_add_read(zrouter.master, rtadv_read, zns, val,
&rtadv->ra_read);
break;
default:
zebra/zebra_errors.c \
# end
+zebra/debug_clippy.c: $(CLIPPY_DEPS)
+zebra/debug.$(OBJEXT): zebra/debug_clippy.c
+
zebra/zebra_mlag_clippy.c: $(CLIPPY_DEPS)
zebra/zebra_mlag.$(OBJEXT): zebra/zebra_mlag_clippy.c
#include "lib/libfrr.h"
#include "lib/sockopt.h"
+#include "zebra/zebra_router.h"
#include "zebra/rib.h"
#include "zebra/zebra_memory.h"
#include "zebra/zebra_ns.h"
p->prefixlen, ifc->ifp->name);
}
- for (ALL_LIST_ELEMENTS(zebrad.client_list, node, nnode, client))
+ for (ALL_LIST_ELEMENTS(zrouter.client_list, node, nnode, client))
zsend_interface_nbr_address(ZEBRA_INTERFACE_NBR_ADDRESS_ADD,
client, ifp, ifc);
}
p->prefixlen, ifc->ifp->name);
}
- for (ALL_LIST_ELEMENTS(zebrad.client_list, node, nnode, client))
+ for (ALL_LIST_ELEMENTS(zrouter.client_list, node, nnode, client))
zsend_interface_nbr_address(ZEBRA_INTERFACE_NBR_ADDRESS_DELETE,
client, ifp, ifc);
}
zlog_debug("%s: Notifying %u", __PRETTY_FUNCTION__,
rule->rule.unique);
- for (ALL_LIST_ELEMENTS_RO(zebrad.client_list, node, client)) {
+ for (ALL_LIST_ELEMENTS_RO(zrouter.client_list, node, client)) {
if (rule->sock == client->sock)
break;
}
zlog_debug("%s: Notifying %u", __PRETTY_FUNCTION__,
ipset->unique);
- for (ALL_LIST_ELEMENTS_RO(zebrad.client_list, node, client)) {
+ for (ALL_LIST_ELEMENTS_RO(zrouter.client_list, node, client)) {
if (ipset->sock == client->sock)
break;
}
zlog_debug("%s: Notifying %u", __PRETTY_FUNCTION__,
ipset->unique);
- for (ALL_LIST_ELEMENTS_RO(zebrad.client_list, node, client)) {
+ for (ALL_LIST_ELEMENTS_RO(zrouter.client_list, node, client)) {
if (ipset->sock == client->sock)
break;
}
zlog_debug("%s: Notifying %u", __PRETTY_FUNCTION__,
iptable->unique);
- for (ALL_LIST_ELEMENTS_RO(zebrad.client_list, node, client)) {
+ for (ALL_LIST_ELEMENTS_RO(zrouter.client_list, node, client)) {
if (iptable->sock == client->sock)
break;
}
zserv_send_message(client, s);
}
+void zsend_capabilities_all_clients(void)
+{
+ struct listnode *node, *nnode;
+ struct zebra_vrf *zvrf;
+ struct zserv *client;
+
+ zvrf = vrf_info_lookup(VRF_DEFAULT);
+ for (ALL_LIST_ELEMENTS(zrouter.client_list, node, nnode, client)) {
+ zsend_capabilities(client, zvrf);
+ }
+}
+
/* Tie up route-type and client->sock */
static void zread_hello(ZAPI_HANDLER_ARGS)
{
enum zapi_iptable_notify_owner note);
extern void zserv_nexthop_num_warn(const char *caller, const struct prefix *p,
const unsigned int nexthop_num);
+
+extern void zsend_capabilities_all_clients(void);
#include "lib/zebra.h"
#include "zebra/zebra_router.h"
#include "zebra/zebra_memory.h"
-#include "zebra/zserv.h"
+#include "zebra/zebra_router.h"
#include "zebra/zebra_dplane.h"
#include "zebra/rt.h"
#include "zebra/debug.h"
/* We appear to be done - schedule a final callback event
* for the zebra main pthread.
*/
- thread_add_event(zebrad.master, zebra_finalize, NULL, 0, NULL);
+ thread_add_event(zrouter.master, zebra_finalize, NULL, 0, NULL);
}
return 0;
/*
* Initialize the dataplane module during startup, internal/private version
*/
-static void zebra_dplane_init_internal(struct zebra_t *zebra)
+static void zebra_dplane_init_internal(void)
{
memset(&zdplane_info, 0, sizeof(zdplane_info));
*/
void zebra_dplane_init(int (*results_fp)(struct dplane_ctx_q *))
{
- zebra_dplane_init_internal(&zebrad);
+ zebra_dplane_init_internal();
zdplane_info.dg_results_cb = results_fp;
}
#include "hook.h"
#include "zebra/zebra_mlag.h"
+#include "zebra/zebra_router.h"
+#include "zebra/zapi_msg.h"
+#include "zebra/debug.h"
#ifndef VTYSH_EXTRACT_PL
#include "zebra/zebra_mlag_clippy.c"
#endif
-enum mlag_role role = MLAG_ROLE_NONE;
-
enum mlag_role zebra_mlag_get_role(void)
{
- return role;
+ return zrouter.mlag_info.role;
}
DEFUN_HIDDEN (show_mlag,
char buf[80];
vty_out(vty, "MLag is configured to: %s\n",
- mlag_role2str(role, buf, sizeof(buf)));
+ mlag_role2str(zrouter.mlag_info.role, buf, sizeof(buf)));
return CMD_SUCCESS;
}
"Mlag is setup to be primary\n"
"Mlag is setup to be the secondary\n")
{
+ enum mlag_role orig = zrouter.mlag_info.role;
+ char buf1[80], buf2[80];
+
if (none)
- role = MLAG_ROLE_NONE;
+ zrouter.mlag_info.role = MLAG_ROLE_NONE;
if (primary)
- role = MLAG_ROLE_PRIMARY;
+ zrouter.mlag_info.role = MLAG_ROLE_PRIMARY;
if (secondary)
- role = MLAG_ROLE_SECONDARY;
+ zrouter.mlag_info.role = MLAG_ROLE_SECONDARY;
+
+ if (IS_ZEBRA_DEBUG_MLAG)
+ zlog_debug("Test: Changing role from %s to %s",
+ mlag_role2str(orig, buf1, sizeof(buf1)),
+ mlag_role2str(orig, buf2, sizeof(buf2)));
+
+ if (orig != zrouter.mlag_info.role)
+ zsend_capabilities_all_clients();
return CMD_SUCCESS;
}
#include "zebra/rt.h"
#include "zebra/interface.h"
#include "zebra/zserv.h"
+#include "zebra/zebra_router.h"
#include "zebra/redistribute.h"
#include "zebra/debug.h"
#include "zebra/zebra_memory.h"
int mpls_enabled;
-/* Default rtm_table for all clients */
-extern struct zebra_t zebrad;
-
/* static function declarations */
static void fec_evaluate(struct zebra_vrf *zvrf);
static int snhlfe_del(zebra_snhlfe_t *snhlfe);
static int snhlfe_del_all(zebra_slsp_t *slsp);
static char *snhlfe2str(zebra_snhlfe_t *snhlfe, char *buf, int size);
-static int mpls_processq_init(struct zebra_t *zebra);
/* Static functions */
if (CHECK_FLAG(lsp->flags, LSP_FLAG_SCHEDULED))
return 0;
- if (zebrad.lsp_process_q == NULL) {
+ if (zrouter.lsp_process_q == NULL) {
flog_err(EC_ZEBRA_WQ_NONEXISTENT,
"%s: work_queue does not exist!", __func__);
return -1;
}
- work_queue_add(zebrad.lsp_process_q, lsp);
+ work_queue_add(zrouter.lsp_process_q, lsp);
SET_FLAG(lsp->flags, LSP_FLAG_SCHEDULED);
return 0;
}
/*
* Initialize work queue for processing changed LSPs.
*/
-static int mpls_processq_init(struct zebra_t *zebra)
+static int mpls_processq_init(void)
{
- zebra->lsp_process_q = work_queue_new(zebra->master, "LSP processing");
- if (!zebra->lsp_process_q) {
+ zrouter.lsp_process_q = work_queue_new(zrouter.master, "LSP processing");
+ if (!zrouter.lsp_process_q) {
flog_err(EC_ZEBRA_WQ_NONEXISTENT,
"%s: could not initialise work queue!", __func__);
return -1;
}
- zebra->lsp_process_q->spec.workfunc = &lsp_process;
- zebra->lsp_process_q->spec.del_item_data = &lsp_processq_del;
- zebra->lsp_process_q->spec.errorfunc = NULL;
- zebra->lsp_process_q->spec.completion_func = &lsp_processq_complete;
- zebra->lsp_process_q->spec.max_retries = 0;
- zebra->lsp_process_q->spec.hold = 10;
+ zrouter.lsp_process_q->spec.workfunc = &lsp_process;
+ zrouter.lsp_process_q->spec.del_item_data = &lsp_processq_del;
+ zrouter.lsp_process_q->spec.errorfunc = NULL;
+ zrouter.lsp_process_q->spec.completion_func = &lsp_processq_complete;
+ zrouter.lsp_process_q->spec.max_retries = 0;
+ zrouter.lsp_process_q->spec.hold = 10;
return 0;
}
return;
}
- if (!mpls_processq_init(&zebrad))
+ if (!mpls_processq_init())
mpls_enabled = 1;
hook_register(zserv_client_close, zebra_mpls_cleanup_fecs_for_client);
#include "memory.h"
#include "lib_errors.h"
-#include "zserv.h"
+#include "zebra_router.h"
#include "zebra_memory.h"
#endif /* defined(HAVE_NETLINK) */
XFREE(MTYPE_NETNS_MISC, zns_info);
return 0;
}
- thread_add_timer_msec(zebrad.master, zebra_ns_ready_read,
+ thread_add_timer_msec(zrouter.master, zebra_ns_ready_read,
(void *)zns_info, ZEBRA_NS_POLLING_INTERVAL_MSEC,
NULL);
return 0;
ssize_t len;
zebra_netns_notify_current = thread_add_read(
- zebrad.master, zebra_ns_notify_read, NULL, fd_monitor, NULL);
+ zrouter.master, zebra_ns_notify_read, NULL, fd_monitor, NULL);
len = read(fd_monitor, buf, sizeof(buf));
if (len < 0) {
flog_err_sys(EC_ZEBRA_NS_NOTIFY_READ,
sizeof(struct zebra_netns_info));
netnsinfo->retries = ZEBRA_NS_POLLING_MAX_RETRIES;
netnsinfo->netnspath = netnspath;
- thread_add_timer_msec(zebrad.master, zebra_ns_ready_read,
+ thread_add_timer_msec(zrouter.master, zebra_ns_ready_read,
(void *)netnsinfo, 0, NULL);
}
return 0;
safe_strerror(errno));
}
zebra_netns_notify_current = thread_add_read(
- zebrad.master, zebra_ns_notify_read, NULL, fd_monitor, NULL);
+ zrouter.master, zebra_ns_notify_read, NULL, fd_monitor, NULL);
}
void zebra_ns_notify_close(void)
#include "zebra/zebra_errors.h"
#include "zebra/zebra_ptm.h"
#include "zebra/zebra_ptm_redistribute.h"
-#include "zebra/zserv.h"
+#include "zebra/zebra_router.h"
#include "zebra_vrf.h"
/*
ptm_cb.ptm_sock = -1;
zebra_ptm_reset_status(0);
ptm_cb.t_timer = NULL;
- thread_add_timer(zebrad.master, zebra_ptm_connect, NULL,
+ thread_add_timer(zrouter.master, zebra_ptm_connect, NULL,
ptm_cb.reconnect_time, &ptm_cb.t_timer);
return (-1);
case BUFFER_PENDING:
ptm_cb.t_write = NULL;
- thread_add_write(zebrad.master, zebra_ptm_flush_messages, NULL,
+ thread_add_write(zrouter.master, zebra_ptm_flush_messages, NULL,
ptm_cb.ptm_sock, &ptm_cb.t_write);
break;
case BUFFER_EMPTY:
ptm_cb.ptm_sock = -1;
zebra_ptm_reset_status(0);
ptm_cb.t_timer = NULL;
- thread_add_timer(zebrad.master, zebra_ptm_connect, NULL,
+ thread_add_timer(zrouter.master, zebra_ptm_connect, NULL,
ptm_cb.reconnect_time, &ptm_cb.t_timer);
return -1;
case BUFFER_EMPTY:
THREAD_OFF(ptm_cb.t_write);
break;
case BUFFER_PENDING:
- thread_add_write(zebrad.master, zebra_ptm_flush_messages, NULL,
+ thread_add_write(zrouter.master, zebra_ptm_flush_messages, NULL,
ptm_cb.ptm_sock, &ptm_cb.t_write);
break;
}
if (ptm_cb.ptm_sock != -1) {
if (init) {
ptm_cb.t_read = NULL;
- thread_add_read(zebrad.master, zebra_ptm_sock_read,
+ thread_add_read(zrouter.master, zebra_ptm_sock_read,
NULL, ptm_cb.ptm_sock, &ptm_cb.t_read);
zebra_bfd_peer_replay_req();
}
ptm_cb.reconnect_time = ZEBRA_PTM_RECONNECT_TIME_MAX;
ptm_cb.t_timer = NULL;
- thread_add_timer(zebrad.master, zebra_ptm_connect, NULL,
+ thread_add_timer(zrouter.master, zebra_ptm_connect, NULL,
ptm_cb.reconnect_time, &ptm_cb.t_timer);
} else if (ptm_cb.reconnect_time >= ZEBRA_PTM_RECONNECT_TIME_MAX) {
ptm_cb.reconnect_time = ZEBRA_PTM_RECONNECT_TIME_INITIAL;
ptm_cb.ptm_sock = -1;
zebra_ptm_reset_status(0);
ptm_cb.t_timer = NULL;
- thread_add_timer(zebrad.master, zebra_ptm_connect, NULL,
+ thread_add_timer(zrouter.master, zebra_ptm_connect, NULL,
ptm_cb.reconnect_time,
&ptm_cb.t_timer);
return (-1);
}
ptm_cb.t_read = NULL;
- thread_add_read(zebrad.master, zebra_ptm_sock_read, NULL,
+ thread_add_read(zrouter.master, zebra_ptm_sock_read, NULL,
ptm_cb.ptm_sock, &ptm_cb.t_read);
return 0;
if (ptm_cb.ptm_sock == -1) {
ptm_cb.t_timer = NULL;
- thread_add_timer(zebrad.master, zebra_ptm_connect, NULL,
+ thread_add_timer(zrouter.master, zebra_ptm_connect, NULL,
ptm_cb.reconnect_time, &ptm_cb.t_timer);
return;
}
if (ptm_cb.ptm_sock == -1) {
ptm_cb.t_timer = NULL;
- thread_add_timer(zebrad.master, zebra_ptm_connect, NULL,
+ thread_add_timer(zrouter.master, zebra_ptm_connect, NULL,
ptm_cb.reconnect_time, &ptm_cb.t_timer);
return;
}
if (ptm_cb.ptm_sock == -1) {
ptm_cb.t_timer = NULL;
- thread_add_timer(zebrad.master, zebra_ptm_connect, NULL,
+ thread_add_timer(zrouter.master, zebra_ptm_connect, NULL,
ptm_cb.reconnect_time, &ptm_cb.t_timer);
return;
}
if (ptm_cb.ptm_sock == -1) {
ptm_cb.t_timer = NULL;
- thread_add_timer(zebrad.master, zebra_ptm_connect, NULL,
+ thread_add_timer(zrouter.master, zebra_ptm_connect, NULL,
ptm_cb.reconnect_time, &ptm_cb.t_timer);
return 0;
}
}
/* Send message to all running BFDd daemons. */
- for (ALL_LIST_ELEMENTS_RO(zebrad.client_list, node, client)) {
+ for (ALL_LIST_ELEMENTS_RO(zrouter.client_list, node, client)) {
if (client->proto != ZEBRA_ROUTE_BFD)
continue;
}
/* Send message to all running client daemons. */
- for (ALL_LIST_ELEMENTS_RO(zebrad.client_list, node, client)) {
+ for (ALL_LIST_ELEMENTS_RO(zrouter.client_list, node, client)) {
if (!IS_BFD_ENABLED_PROTOCOL(client->proto))
continue;
#include "prefix.h"
#include "vty.h"
#include "stream.h"
-#include "zebra/zserv.h"
+#include "zebra/zebra_router.h"
#include "zebra/zapi_msg.h"
#include "zebra/zebra_ptm.h"
#include "zebra/zebra_ptm_redistribute.h"
struct listnode *node, *nnode;
struct zserv *client;
- for (ALL_LIST_ELEMENTS(zebrad.client_list, node, nnode, client)) {
+ for (ALL_LIST_ELEMENTS(zrouter.client_list, node, nnode, client)) {
if (!IS_BFD_ENABLED_PROTOCOL(client->proto))
continue;
struct listnode *node, *nnode;
struct zserv *client;
- for (ALL_LIST_ELEMENTS(zebrad.client_list, node, nnode, client)) {
+ for (ALL_LIST_ELEMENTS(zrouter.client_list, node, nnode, client)) {
if (!IS_BFD_ENABLED_PROTOCOL(client->proto))
continue;
#include "zebra/debug.h"
#include "zebra/rib.h"
-#include "zebra/zserv.h"
+#include "zebra/zebra_router.h"
#include "zebra/zapi_msg.h"
#include "zebra/zebra_rnh.h"
#include "zebra/zebra_vrf.h"
#define MPLS_NO_LABEL MPLS_INVALID_LABEL
-extern struct zebra_t zebrad;
-
static int zebra_pw_enabled(struct zebra_pw *);
static void zebra_pw_install(struct zebra_pw *);
static void zebra_pw_uninstall(struct zebra_pw *);
/* schedule to retry later */
THREAD_TIMER_OFF(pw->install_retry_timer);
- thread_add_timer(zebrad.master, zebra_pw_install_retry, pw,
+ thread_add_timer(zrouter.master, zebra_pw_install_retry, pw,
PW_INSTALL_RETRY_INTERVAL, &pw->install_retry_timer);
zebra_pw_update_status(pw, PW_STATUS_DOWN);
int is_zebra_main_routing_table(uint32_t table_id)
{
if ((table_id == RT_TABLE_MAIN)
- || (table_id == zebrad.rtm_table_default))
+ || (table_id == zrouter.rtm_table_default))
return 1;
return 0;
}
queue_len, queue_limit);
/* Ensure that the meta-queue is actually enqueued */
- if (work_queue_empty(zebrad.ribq))
- work_queue_add(zebrad.ribq, zebrad.mq);
+ if (work_queue_empty(zrouter.ribq))
+ work_queue_add(zrouter.ribq, zrouter.mq);
return WQ_QUEUE_BLOCKED;
}
return;
}
- if (zebrad.ribq == NULL) {
+ if (zrouter.ribq == NULL) {
flog_err(EC_ZEBRA_WQ_NONEXISTENT,
"%s: work_queue does not exist!", __func__);
return;
* holder, if necessary, then push the work into it in any case.
* This semantics was introduced after 0.99.9 release.
*/
- if (work_queue_empty(zebrad.ribq))
- work_queue_add(zebrad.ribq, zebrad.mq);
+ if (work_queue_empty(zrouter.ribq))
+ work_queue_add(zrouter.ribq, zrouter.mq);
- rib_meta_queue_add(zebrad.mq, rn);
+ rib_meta_queue_add(zrouter.mq, rn);
return;
}
}
/* initialise zebra rib work queue */
-static void rib_queue_init(struct zebra_t *zebra)
+static void rib_queue_init(void)
{
- assert(zebra);
-
- if (!(zebra->ribq =
- work_queue_new(zebra->master, "route_node processing"))) {
+ if (!(zrouter.ribq = work_queue_new(zrouter.master,
+ "route_node processing"))) {
flog_err(EC_ZEBRA_WQ_NONEXISTENT,
"%s: could not initialise work queue!", __func__);
return;
}
/* fill in the work queue spec */
- zebra->ribq->spec.workfunc = &meta_queue_process;
- zebra->ribq->spec.errorfunc = NULL;
- zebra->ribq->spec.completion_func = &meta_queue_process_complete;
+ zrouter.ribq->spec.workfunc = &meta_queue_process;
+ zrouter.ribq->spec.errorfunc = NULL;
+ zrouter.ribq->spec.completion_func = &meta_queue_process_complete;
/* XXX: TODO: These should be runtime configurable via vty */
- zebra->ribq->spec.max_retries = 3;
- zebra->ribq->spec.hold = ZEBRA_RIB_PROCESS_HOLD_TIME;
- zebra->ribq->spec.retry = ZEBRA_RIB_PROCESS_RETRY_TIME;
+ zrouter.ribq->spec.max_retries = 3;
+ zrouter.ribq->spec.hold = ZEBRA_RIB_PROCESS_HOLD_TIME;
+ zrouter.ribq->spec.retry = ZEBRA_RIB_PROCESS_RETRY_TIME;
- if (!(zebra->mq = meta_queue_new())) {
+ if (!(zrouter.mq = meta_queue_new())) {
flog_err(EC_ZEBRA_WQ_NONEXISTENT,
"%s: could not initialise meta queue!", __func__);
return;
pthread_mutex_unlock(&dplane_mutex);
/* Ensure event is signalled to zebra main pthread */
- thread_add_event(zebrad.master, rib_process_dplane_results, NULL, 0,
+ thread_add_event(zrouter.master, rib_process_dplane_results, NULL, 0,
&t_dplane);
return 0;
/* Routing information base initialize. */
void rib_init(void)
{
- rib_queue_init(&zebrad);
+ rib_queue_init();
/* Init dataplane, and register for results */
pthread_mutex_init(&dplane_mutex, NULL);
#include "vrf.h"
#include "frrstr.h"
-#include "zebra/zserv.h"
+#include "zebra/zebra_router.h"
#include "zebra/redistribute.h"
#include "zebra/debug.h"
#include "zebra/zebra_rnh.h"
/* rmap_update_timer of 0 means don't do route updates */
if (zebra_rmap_update_timer && !zebra_t_rmap_update) {
zebra_t_rmap_update = NULL;
- thread_add_timer(zebrad.master, zebra_route_map_update_timer,
+ thread_add_timer(zrouter.master, zebra_route_map_update_timer,
NULL, zebra_rmap_update_timer,
&zebra_t_rmap_update);
}
zebra_router_free_table(zrt);
}
+ work_queue_free_and_null(&zrouter.ribq);
+ meta_queue_free(zrouter.mq);
+
zebra_vxlan_disable();
zebra_mlag_terminate();
{
zrouter.sequence_num = 0;
+ zrouter.rtm_table_default = 0;
+ zrouter.packets_to_process = ZEBRA_ZAPI_PACKETS_TO_PROCESS;
+
zebra_vxlan_init();
zebra_mlag_init();
#ifndef __ZEBRA_ROUTER_H__
#define __ZEBRA_ROUTER_H__
+#include "lib/mlag.h"
+
#include "zebra/zebra_ns.h"
/*
RB_PROTOTYPE(zebra_router_table_head, zebra_router_table,
zebra_router_table_entry, zebra_router_table_entry_compare)
+struct zebra_mlag_info {
+ /* Role this zebra router is playing */
+ enum mlag_role role;
+
+ /* The peerlink being used for mlag */
+ char *peerlink;
+ ifindex_t peerlink_ifindex;
+
+ /* The system mac being used */
+ struct ethaddr mac;
+};
+
struct zebra_router {
+ /* Thread master */
+ struct thread_master *master;
+
+ /* Lists of clients who have connected to us */
+ struct list *client_list;
struct zebra_router_table_head tables;
/* A sequence number used for tracking routes */
_Atomic uint32_t sequence_num;
+
+ /* The default table used for this router */
+ uint32_t rtm_table_default;
+
+ /* rib work queue */
+#define ZEBRA_RIB_PROCESS_HOLD_TIME 10
+#define ZEBRA_RIB_PROCESS_RETRY_TIME 1
+ struct work_queue *ribq;
+
+ /* Meta Queue Information */
+ struct meta_queue *mq;
+
+ /* LSP work queue */
+ struct work_queue *lsp_process_q;
+
+#define ZEBRA_ZAPI_PACKETS_TO_PROCESS 1000
+ _Atomic uint32_t packets_to_process;
+
+ /* Mlag information for the router */
+ struct zebra_mlag_info mlag_info;
};
extern struct zebra_router zrouter;
#include "zebra/zebra_netns_notify.h"
#include "zebra/zebra_routemap.h"
-extern struct zebra_t zebrad;
-
static void zebra_vrf_table_create(struct zebra_vrf *zvrf, afi_t afi,
safi_t safi);
static void zebra_rnhtable_node_cleanup(struct route_table *table,
if (IS_ZEBRA_DEBUG_EVENT)
zlog_debug("MESSAGE: ZEBRA_VRF_ADD %s", zvrf_name(zvrf));
- for (ALL_LIST_ELEMENTS(zebrad.client_list, node, nnode, client))
+ for (ALL_LIST_ELEMENTS(zrouter.client_list, node, nnode, client))
zsend_vrf_add(client, zvrf);
}
if (IS_ZEBRA_DEBUG_EVENT)
zlog_debug("MESSAGE: ZEBRA_VRF_DELETE %s", zvrf_name(zvrf));
- for (ALL_LIST_ELEMENTS(zebrad.client_list, node, nnode, client))
+ for (ALL_LIST_ELEMENTS(zrouter.client_list, node, nnode, client))
zsend_vrf_delete(client, zvrf);
}
struct route_node *rnode;
rib_dest_t *dest;
- for (ALL_LIST_ELEMENTS(zebrad.mq->subq[i], lnode, nnode,
+ for (ALL_LIST_ELEMENTS(zrouter.mq->subq[i], lnode, nnode,
rnode)) {
dest = rib_dest_from_rnode(rnode);
if (dest && rib_dest_vrf(dest) == zvrf) {
route_unlock_node(rnode);
- list_delete_node(zebrad.mq->subq[i], lnode);
- zebrad.mq->size--;
+ list_delete_node(zrouter.mq->subq[i], lnode);
+ zrouter.mq->size--;
}
}
}
struct route_node *rnode;
rib_dest_t *dest;
- for (ALL_LIST_ELEMENTS(zebrad.mq->subq[i], lnode, nnode,
+ for (ALL_LIST_ELEMENTS(zrouter.mq->subq[i], lnode, nnode,
rnode)) {
dest = rib_dest_from_rnode(rnode);
if (dest && rib_dest_vrf(dest) == zvrf) {
route_unlock_node(rnode);
- list_delete_node(zebrad.mq->subq[i], lnode);
- zebrad.mq->size--;
+ list_delete_node(zrouter.mq->subq[i], lnode);
+ zrouter.mq->size--;
}
}
}
if (vrf_id == VRF_DEFAULT) {
if (table_id == RT_TABLE_MAIN
- || table_id == zebrad.rtm_table_default)
+ || table_id == zrouter.rtm_table_default)
table = zebra_vrf_table(afi, safi, vrf_id);
else
table = zebra_vrf_other_route_table(afi, table_id,
vrf_id);
} else if (vrf_is_backend_netns()) {
if (table_id == RT_TABLE_MAIN
- || table_id == zebrad.rtm_table_default)
+ || table_id == zrouter.rtm_table_default)
table = zebra_vrf_table(afi, safi, vrf_id);
else
table = zebra_vrf_other_route_table(afi, table_id,
return NULL;
if ((table_id != RT_TABLE_MAIN)
- && (table_id != zebrad.rtm_table_default)) {
+ && (table_id != zrouter.rtm_table_default)) {
if (zvrf->table_id == RT_TABLE_MAIN ||
- zvrf->table_id == zebrad.rtm_table_default) {
+ zvrf->table_id == zrouter.rtm_table_default) {
/* this VRF use default table
* so in all cases, it does not use specific table
* so it is possible to configure tables in this VRF
if (CHECK_FLAG(re->status, ROUTE_ENTRY_QUEUED))
return 'q';
- return 'f';
+ return 'r';
}
if (CHECK_FLAG(re->status, ROUTE_ENTRY_QUEUED))
{
uint32_t packets = strtoul(argv[2]->arg, NULL, 10);
- atomic_store_explicit(&zebrad.packets_to_process, packets,
+ atomic_store_explicit(&zrouter.packets_to_process, packets,
memory_order_relaxed);
return CMD_SUCCESS;
"Zapi Protocol\n"
"Number of packets to process before relinquishing thread\n")
{
- atomic_store_explicit(&zebrad.packets_to_process,
+ atomic_store_explicit(&zrouter.packets_to_process,
ZEBRA_ZAPI_PACKETS_TO_PROCESS,
memory_order_relaxed);
"Time in milliseconds\n")
{
uint32_t timer = strtoul(argv[2]->arg, NULL, 10);
- zebrad.ribq->spec.hold = timer;
+ zrouter.ribq->spec.hold = timer;
return CMD_SUCCESS;
}
"Work Queue\n"
"Time in milliseconds\n")
{
- zebrad.ribq->spec.hold = ZEBRA_RIB_PROCESS_HOLD_TIME;
+ zrouter.ribq->spec.hold = ZEBRA_RIB_PROCESS_HOLD_TIME;
return CMD_SUCCESS;
}
if (zebra_rnh_ipv6_default_route)
vty_out(vty, "ipv6 nht resolve-via-default\n");
- if (zebrad.ribq->spec.hold != ZEBRA_RIB_PROCESS_HOLD_TIME)
- vty_out(vty, "zebra work-queue %u\n", zebrad.ribq->spec.hold);
+ if (zrouter.ribq->spec.hold != ZEBRA_RIB_PROCESS_HOLD_TIME)
+ vty_out(vty, "zebra work-queue %u\n", zrouter.ribq->spec.hold);
- if (zebrad.packets_to_process != ZEBRA_ZAPI_PACKETS_TO_PROCESS)
+ if (zrouter.packets_to_process != ZEBRA_ZAPI_PACKETS_TO_PROCESS)
vty_out(vty, "zebra zapi-packets %u\n",
- zebrad.packets_to_process);
+ zrouter.packets_to_process);
enum multicast_mode ipv4_multicast_mode = multicast_mode_ipv4_get();
SHOW_STR
"default routing table to use for all clients\n")
{
- vty_out(vty, "table %d\n", zebrad.rtm_table_default);
+ vty_out(vty, "table %d\n", zrouter.rtm_table_default);
return CMD_SUCCESS;
}
"Configure target kernel routing table\n"
"TABLE integer\n")
{
- zebrad.rtm_table_default = strtol(argv[1]->arg, (char **)0, 10);
+ zrouter.rtm_table_default = strtol(argv[1]->arg, (char **)0, 10);
return CMD_SUCCESS;
}
"Configure target kernel routing table\n"
"TABLE integer\n")
{
- zebrad.rtm_table_default = 0;
+ zrouter.rtm_table_default = 0;
return CMD_SUCCESS;
}
#endif
/* Table configuration write function. */
static int config_write_table(struct vty *vty)
{
- if (zebrad.rtm_table_default)
- vty_out(vty, "table %d\n", zebrad.rtm_table_default);
+ if (zrouter.rtm_table_default)
+ vty_out(vty, "table %d\n", zrouter.rtm_table_default);
return 0;
}
#include "zebra/zebra_vrf.h"
#include "zebra/zebra_vxlan.h"
#include "zebra/zebra_vxlan_private.h"
-#include "zebra/zserv.h"
+#include "zebra/zebra_router.h"
DEFINE_MTYPE_STATIC(ZEBRA, HOST_PREFIX, "host prefix");
DEFINE_MTYPE_STATIC(ZEBRA, ZVNI, "VNI hash");
sizeof(buf)),
mac->flags, zvrf->dad_freeze_time);
- thread_add_timer(zebrad.master,
+ thread_add_timer(zrouter.master,
zebra_vxlan_dad_mac_auto_recovery_exp,
mac, zvrf->dad_freeze_time,
&mac->dad_mac_auto_recovery_timer);
ipaddr2str(&nbr->ip, buf1, sizeof(buf1)),
nbr->flags, zvrf->dad_freeze_time);
- thread_add_timer(zebrad.master,
+ thread_add_timer(zrouter.master,
zebra_vxlan_dad_ip_auto_recovery_exp,
nbr, zvrf->dad_freeze_time,
&nbr->dad_ip_auto_recovery_timer);
#include "zebra/zapi_msg.h" /* for zserv_handle_commands */
#include "zebra/zebra_vrf.h" /* for zebra_vrf_lookup_by_id, zvrf */
#include "zebra/zserv.h" /* for zserv */
+#include "zebra/zebra_router.h"
#include "zebra/zebra_errors.h" /* for error messages */
/* clang-format on */
/* privileges */
extern struct zebra_privs_t zserv_privs;
+/* The listener socket for clients connecting to us */
+static int zsock;
+
/*
* Client thread events.
*
uint32_t p2p;
struct zmsghdr hdr;
- p2p_orig = atomic_load_explicit(&zebrad.packets_to_process,
+ p2p_orig = atomic_load_explicit(&zrouter.packets_to_process,
memory_order_relaxed);
cache = stream_fifo_new();
p2p = p2p_orig;
* with the message is executed. This proceeds until there are no more messages,
* an error occurs, or the processing limit is reached.
*
- * The client's I/O thread can push at most zebrad.packets_to_process messages
+ * The client's I/O thread can push at most zrouter.packets_to_process messages
* onto the input buffer before notifying us there are packets to read. As long
- * as we always process zebrad.packets_to_process messages here, then we can
+ * as we always process zrouter.packets_to_process messages here, then we can
* rely on the read thread to handle queuing this task enough times to process
* everything on the input queue.
*/
struct zserv *client = THREAD_ARG(thread);
struct stream *msg;
struct stream_fifo *cache = stream_fifo_new();
- uint32_t p2p = zebrad.packets_to_process;
+ uint32_t p2p = zrouter.packets_to_process;
bool need_resched = false;
pthread_mutex_lock(&client->ibuf_mtx);
zlog_debug("Closing client '%s'",
zebra_route_string(client->proto));
- thread_cancel_event(zebrad.master, client);
+ thread_cancel_event(zrouter.master, client);
THREAD_OFF(client->t_cleanup);
THREAD_OFF(client->t_process);
client->pthread = NULL;
/* remove from client list */
- listnode_delete(zebrad.client_list, client);
+ listnode_delete(zrouter.client_list, client);
/* delete client */
zserv_client_free(client);
client->wb = buffer_new(0);
/* Set table number. */
- client->rtm_table = zebrad.rtm_table_default;
+ client->rtm_table = zrouter.rtm_table_default;
atomic_store_explicit(&client->connect_time, (uint32_t) monotime(NULL),
memory_order_relaxed);
client->is_synchronous = 0;
/* Add this client to linked list. */
- listnode_add(zebrad.client_list, client);
+ listnode_add(zrouter.client_list, client);
struct frr_pthread_attr zclient_pthr_attrs = {
.start = frr_pthread_attr_default.start,
old_mask = umask(0077);
/* Make UNIX domain socket. */
- zebrad.sock = socket(sa.ss_family, SOCK_STREAM, 0);
- if (zebrad.sock < 0) {
+ zsock = socket(sa.ss_family, SOCK_STREAM, 0);
+ if (zsock < 0) {
flog_err_sys(EC_LIB_SOCKET, "Can't create zserv socket: %s",
safe_strerror(errno));
return;
}
if (sa.ss_family != AF_UNIX) {
- sockopt_reuseaddr(zebrad.sock);
- sockopt_reuseport(zebrad.sock);
+ sockopt_reuseaddr(zsock);
+ sockopt_reuseport(zsock);
} else {
struct sockaddr_un *suna = (struct sockaddr_un *)&sa;
if (suna->sun_path[0])
}
frr_elevate_privs(&zserv_privs) {
- setsockopt_so_recvbuf(zebrad.sock, 1048576);
- setsockopt_so_sendbuf(zebrad.sock, 1048576);
+ setsockopt_so_recvbuf(zsock, 1048576);
+ setsockopt_so_sendbuf(zsock, 1048576);
}
frr_elevate_privs((sa.ss_family != AF_UNIX) ? &zserv_privs : NULL) {
- ret = bind(zebrad.sock, (struct sockaddr *)&sa, sa_len);
+ ret = bind(zsock, (struct sockaddr *)&sa, sa_len);
}
if (ret < 0) {
flog_err_sys(EC_LIB_SOCKET, "Can't bind zserv socket on %s: %s",
path, safe_strerror(errno));
- close(zebrad.sock);
- zebrad.sock = -1;
+ close(zsock);
+ zsock = -1;
return;
}
- ret = listen(zebrad.sock, 5);
+ ret = listen(zsock, 5);
if (ret < 0) {
flog_err_sys(EC_LIB_SOCKET,
"Can't listen to zserv socket %s: %s", path,
safe_strerror(errno));
- close(zebrad.sock);
- zebrad.sock = -1;
+ close(zsock);
+ zsock = -1;
return;
}
{
switch (event) {
case ZSERV_ACCEPT:
- thread_add_read(zebrad.master, zserv_accept, NULL, zebrad.sock,
+ thread_add_read(zrouter.master, zserv_accept, NULL, zsock,
NULL);
break;
case ZSERV_PROCESS_MESSAGES:
- thread_add_event(zebrad.master, zserv_process_messages, client,
+ thread_add_event(zrouter.master, zserv_process_messages, client,
0, &client->t_process);
break;
case ZSERV_HANDLE_CLIENT_FAIL:
- thread_add_event(zebrad.master, zserv_handle_client_fail,
+ thread_add_event(zrouter.master, zserv_handle_client_fail,
client, 0, &client->t_cleanup);
}
}
struct listnode *node, *nnode;
struct zserv *client;
- for (ALL_LIST_ELEMENTS(zebrad.client_list, node, nnode, client)) {
+ for (ALL_LIST_ELEMENTS(zrouter.client_list, node, nnode, client)) {
if (client->proto == proto && client->instance == instance)
return client;
}
struct listnode *node;
struct zserv *client;
- for (ALL_LIST_ELEMENTS_RO(zebrad.client_list, node, client))
+ for (ALL_LIST_ELEMENTS_RO(zrouter.client_list, node, client))
zebra_show_client_detail(vty, client);
return CMD_SUCCESS;
vty_out(vty,
"--------------------------------------------------------------------------------\n");
- for (ALL_LIST_ELEMENTS_RO(zebrad.client_list, node, client))
+ for (ALL_LIST_ELEMENTS_RO(zrouter.client_list, node, client))
zebra_show_client_brief(vty, client);
vty_out(vty, "Routes column shows (added+updated)/deleted\n");
void zserv_init(void)
{
/* Client list init. */
- zebrad.client_list = list_new();
+ zrouter.client_list = list_new();
/* Misc init. */
- zebrad.sock = -1;
+ zsock = -1;
install_element(ENABLE_NODE, &show_zebra_client_cmd);
install_element(ENABLE_NODE, &show_zebra_client_summary_cmd);
DECLARE_HOOK(zserv_client_connect, (struct zserv *client), (client));
DECLARE_KOOH(zserv_client_close, (struct zserv *client), (client));
-/* Zebra instance */
-struct zebra_t {
- /* Thread master */
- struct thread_master *master;
- struct list *client_list;
-
- /* Socket */
- int sock;
-
- /* default table */
- uint32_t rtm_table_default;
-
-/* rib work queue */
-#define ZEBRA_RIB_PROCESS_HOLD_TIME 10
-#define ZEBRA_RIB_PROCESS_RETRY_TIME 1
- struct work_queue *ribq;
- struct meta_queue *mq;
-
- /* LSP work queue */
- struct work_queue *lsp_process_q;
-
-#define ZEBRA_ZAPI_PACKETS_TO_PROCESS 1000
- _Atomic uint32_t packets_to_process;
-};
-extern struct zebra_t zebrad;
extern unsigned int multipath_num;
/*