ZCAP_BIND
};
-static struct zebra_privs_t babeld_privs =
+struct zebra_privs_t babeld_privs =
{
#if defined(FRR_USER)
.user = FRR_USER,
void babelz_zebra_init(void)
{
zclient = zclient_new(master);
- zclient_init(zclient, ZEBRA_ROUTE_BABEL, 0);
+ zclient_init(zclient, ZEBRA_ROUTE_BABEL, 0, &babeld_privs);
zclient->zebra_connected = babel_zebra_connected;
zclient->interface_add = babel_interface_add;
struct thread *t_update; /* timers */
};
+extern struct zebra_privs_t babeld_privs;
+
extern void babeld_quagga_init(void);
extern int input_filter(const unsigned char *id,
const unsigned char *prefix, unsigned short plen,
TERM_DEBUG_OFF(neighbor_events, NEIGHBOR_EVENTS);
TERM_DEBUG_OFF(zebra, ZEBRA);
TERM_DEBUG_OFF(allow_martians, ALLOW_MARTIANS);
+ TERM_DEBUG_OFF(nht, NHT);
vty_out(vty, "All possible debugging has been turned off\n");
return CMD_SUCCESS;
vpn->prd.family = AF_UNSPEC;
vpn->prd.prefixlen = 64;
sprintf(buf, "%s:%hu", inet_ntoa(bgp->router_id), vpn->rd_id);
- str2prefix_rd(buf, &vpn->prd);
+ (void)str2prefix_rd(buf, &vpn->prd);
UNSET_FLAG(vpn->flags, VNI_FLAG_RD_CFGD);
}
attr.ecommunity = ecomm;
attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES);
}
+ if (lcomm) {
+ attr.lcommunity = lcomm;
+ attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_LARGE_COMMUNITIES);
+ }
/* Zap multipath attr nexthop so we set nexthop to self */
attr.nexthop.s_addr = 0;
afi_t afi = AFI_MAX;
int idx = 0;
- argv_find_and_parse_afi(argv, argc, &idx, &afi);
+ (void)argv_find_and_parse_afi(argv, argc, &idx, &afi);
ret = str2prefix_rd(argv[5]->arg, &prd);
if (!ret) {
vty_out(vty, "%% Malformed Route Distinguisher\n");
for (afi = AFI_IP; afi < AFI_MAX; afi++)
for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++) {
- /* Ignore inactive AFI/SAFI */
- if (!peer->afc[afi][safi])
- continue;
-
/* process in/out/import/export/default-orig
* route-maps */
bgp_route_map_process_peer(rmap_name, map, peer,
attr.local_pref = bgp->default_local_pref;
- if (afi == AFI_IP)
- str2prefix("0.0.0.0/0", &p);
- else if (afi == AFI_IP6) {
- str2prefix("::/0", &p);
+ memset(&p, 0, sizeof(p));
+ p.family = afi2family(afi);
+ p.prefixlen = 0;
+ if (afi == AFI_IP6) {
/* IPv6 global nexthop must be included. */
attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
* clear adj_out for the 0.0.0.0/0 prefix in the BGP
* table.
*/
- if (afi == AFI_IP)
- str2prefix("0.0.0.0/0", &p);
- else
- str2prefix("::/0", &p);
+ memset(&p, 0, sizeof(p));
+ p.family = afi2family(afi);
+ p.prefixlen = 0;
rn = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi,
&p, NULL);
bpacket_attr_vec_arr_reset(&vecarr);
addpath_encode = bgp_addpath_encode_tx(peer, afi, safi);
- if (afi == AFI_IP)
- str2prefix("0.0.0.0/0", &p);
- else
- str2prefix("::/0", &p);
+ memset(&p, 0, sizeof(p));
+ p.family = afi2family(afi);
+ p.prefixlen = 0;
/* Logging the attribute. */
if (bgp_debug_update(NULL, &p, subgrp->update_group, 0)) {
safi = SUBGRP_SAFI(subgrp);
addpath_encode = bgp_addpath_encode_tx(peer, afi, safi);
- if (afi == AFI_IP)
- str2prefix("0.0.0.0/0", &p);
- else
- str2prefix("::/0", &p);
+ memset(&p, 0, sizeof(p));
+ p.family = afi2family(afi);
+ p.prefixlen = 0;
if (bgp_debug_update(NULL, &p, subgrp->update_group, 0)) {
char buf[PREFIX_STRLEN];
NEIGHBOR_STR
NEIGHBOR_ADDR_STR2
"Remove private ASNs in outbound updates\n"
- "Apply to all AS numbers")
+ "Apply to all AS numbers\n")
{
int idx_peer = 1;
return peer_af_flag_set_vty(vty, argv[idx_peer]->arg, bgp_node_afi(vty),
"Maximum number of prefix accept from this peer\n"
"maximum no. of prefix limit\n"
"Restart bgp connection after limit is exceeded\n"
- "Restart interval in minutes")
+ "Restart interval in minutes\n")
{
int idx_peer = 1;
int idx_number = 3;
"Maximum number of prefix accept from this peer\n"
"maximum no. of prefix limit\n"
"Restart bgp connection after limit is exceeded\n"
- "Restart interval in minutes")
+ "Restart interval in minutes\n")
DEFUN (neighbor_maximum_prefix_threshold_restart,
neighbor_maximum_prefix_threshold_restart_cmd,
->ifindex;
if (!ifindex) {
- if (mpinfo->peer->conf_if
- || mpinfo->peer->ifname)
+ if (mpinfo->peer->conf_if)
+ ifindex = mpinfo->peer->ifp->ifindex;
+ else if (mpinfo->peer->ifname)
ifindex = ifname2ifindex(
- mpinfo->peer->conf_if
- ? mpinfo->peer->conf_if
- : mpinfo->peer->ifname,
+ mpinfo->peer->ifname,
bgp->vrf_id);
else if (mpinfo->peer->nexthop.ifp)
ifindex = mpinfo->peer->nexthop.ifp
return bgp_evpn_local_macip_del(bgp, vni, &mac, &ip);
}
+extern struct zebra_privs_t bgpd_privs;
+
void bgp_zebra_init(struct thread_master *master)
{
zclient_num_connects = 0;
/* Set default values. */
zclient = zclient_new(master);
- zclient_init(zclient, ZEBRA_ROUTE_BGP, 0);
+ zclient_init(zclient, ZEBRA_ROUTE_BGP, 0, &bgpd_privs);
zclient->zebra_connected = bgp_zebra_connected;
zclient->router_id_update = bgp_router_id_update;
zclient->interface_add = bgp_interface_add;
struct prefix pfx_vn;
- rfapiRaddr2Qprefix(&rfd->vn_addr, &pfx_vn);
+ assert(!rfapiRaddr2Qprefix(&rfd->vn_addr, &pfx_vn));
if (prefix_same(&pfx_vn, &pfx_nh))
continue;
}
return CMD_SUCCESS;
}
+extern struct zebra_privs_t bgpd_privs;
/*
* Modeled after bgp_zebra.c'bgp_zebra_init()
{
/* Set default values. */
zclient_vnc = zclient_new(master);
- zclient_init(zclient_vnc, ZEBRA_ROUTE_VNC, 0);
+ zclient_init(zclient_vnc, ZEBRA_ROUTE_VNC, 0, &bgpd_privs);
zclient_vnc->redistribute_route_add = vnc_zebra_read_route;
zclient_vnc->redistribute_route_del = vnc_zebra_read_route;
"rfp example-config-value VALUE",
RFP_SHOW_STR
"Example value to be configured\n"
- "Value to display")
+ "Value to display\n")
{
uint32_t value = 0;
struct rfp_instance_t *rfi = NULL;
#include "table.h"
#include "vty.h"
-extern struct zebra_privs_t eigrpd_privs;
-
#include "eigrpd/eigrp_structs.h"
#include "eigrpd/eigrpd.h"
#include "eigrpd/eigrp_interface.h"
struct route_table *networks; /* EIGRP config networks. */
- struct list *topology_table;
+ struct route_table *topology_table;
uint64_t serno; /* Global serial number counter for topology entry
changes*/
#include "eigrpd/eigrp_fsm.h"
#include "eigrpd/eigrp_memory.h"
-static int eigrp_prefix_entry_cmp(struct eigrp_prefix_entry *,
- struct eigrp_prefix_entry *);
-static void eigrp_prefix_entry_del(struct eigrp_prefix_entry *);
static int eigrp_nexthop_entry_cmp(struct eigrp_nexthop_entry *,
struct eigrp_nexthop_entry *);
* del - assigned function executed before deleting topology node by list
* function
*/
-struct list *eigrp_topology_new()
+struct route_table *eigrp_topology_new()
{
- struct list *new = list_new();
- new->cmp = (int (*)(void *, void *))eigrp_prefix_entry_cmp;
- new->del = (void (*)(void *))eigrp_prefix_entry_del;
-
- return new;
-}
-
-/*
- * Topology node comparison
- */
-
-static int eigrp_prefix_entry_cmp(struct eigrp_prefix_entry *node1,
- struct eigrp_prefix_entry *node2)
-{
- if (node1->af == AF_INET) {
- if (node2->af == AF_INET) {
- if (node1->destination->u.prefix4.s_addr
- < node2->destination->u.prefix4.s_addr)
- return -1;
- if (node1->destination->u.prefix4.s_addr
- > node2->destination->u.prefix4.s_addr)
- return 1;
- else
- return 0;
- } else
- return 1;
- } else
- return 1;
-}
-
-/*
- * Topology node delete
- */
-
-static void eigrp_prefix_entry_del(struct eigrp_prefix_entry *node)
-{
- list_delete_and_null(&node->entries);
+ return route_table_init();
}
/*
/*
* Freeing topology table list
*/
-void eigrp_topology_free(struct list *list)
+void eigrp_topology_free(struct route_table *table)
{
- list_delete_and_null(&list);
+ route_table_finish(table);
}
/*
* Deleting all topology nodes in table
*/
-void eigrp_topology_cleanup(struct list *topology)
+void eigrp_topology_cleanup(struct route_table *table)
{
- assert(topology);
-
- eigrp_topology_delete_all(topology);
+ eigrp_topology_delete_all(table);
}
/*
* Adding topology node to topology table
*/
-void eigrp_prefix_entry_add(struct list *topology,
- struct eigrp_prefix_entry *node)
+void eigrp_prefix_entry_add(struct route_table *topology,
+ struct eigrp_prefix_entry *pe)
{
- if (listnode_lookup(topology, node) == NULL) {
- listnode_add_sort(topology, node);
+ struct route_node *rn;
+
+ rn = route_node_get(topology, pe->destination);
+ if (rn->info) {
+ if (IS_DEBUG_EIGRP_EVENT) {
+ char buf[PREFIX_STRLEN];
+
+ zlog_debug("%s: %s Should we have found this entry in the topo table?",
+ __PRETTY_FUNCTION__,
+ prefix2str(pe->destination, buf,
+ sizeof(buf)));
+ }
}
+
+ rn->info = pe;
+ route_lock_node(rn);
}
/*
/*
* Deleting topology node from topology table
*/
-void eigrp_prefix_entry_delete(struct list *topology,
- struct eigrp_prefix_entry *node)
+void eigrp_prefix_entry_delete(struct route_table *table,
+ struct eigrp_prefix_entry *pe)
{
struct eigrp *eigrp = eigrp_lookup();
+ struct route_node *rn;
+
+ rn = route_node_lookup(table, pe->destination);
+ if (!rn)
+ return;
/*
* Emergency removal of the node from this list.
* Whatever it is.
*/
- listnode_delete(eigrp->topology_changes_internalIPV4, node);
+ listnode_delete(eigrp->topology_changes_internalIPV4, pe);
- if (listnode_lookup(topology, node) != NULL) {
- list_delete_and_null(&node->entries);
- list_delete_and_null(&node->rij);
- listnode_delete(topology, node);
- eigrp_zebra_route_delete(node->destination);
- XFREE(MTYPE_EIGRP_PREFIX_ENTRY, node);
- }
+ list_delete_and_null(&pe->entries);
+ list_delete_and_null(&pe->rij);
+ eigrp_zebra_route_delete(pe->destination);
+
+ rn->info = NULL;
+ route_unlock_node(rn); //Lookup above
+ route_unlock_node(rn); //Initial creation
+ XFREE(MTYPE_EIGRP_PREFIX_ENTRY, pe);
}
/*
/*
* Deleting all nodes from topology table
*/
-void eigrp_topology_delete_all(struct list *topology)
+void eigrp_topology_delete_all(struct route_table *topology)
{
- list_delete_all_node(topology);
+ struct route_node *rn;
+ struct eigrp_prefix_entry *pe;
+
+ for (rn = route_top(topology); rn; rn = route_next(rn)) {
+ pe = rn->info;
+
+ if (!pe)
+ continue;
+
+ eigrp_prefix_entry_delete(topology, pe);
+ }
}
/*
}
struct eigrp_prefix_entry *
-eigrp_topology_table_lookup_ipv4(struct list *topology_table,
+eigrp_topology_table_lookup_ipv4(struct route_table *table,
struct prefix *address)
{
- struct eigrp_prefix_entry *data;
- struct listnode *node;
- for (ALL_LIST_ELEMENTS_RO(topology_table, node, data)) {
- if (prefix_same(data->destination, address))
- return data;
- }
+ struct eigrp_prefix_entry *pe;
+ struct route_node *rn;
- return NULL;
+ rn = route_node_lookup(table, address);
+ if (!rn)
+ return NULL;
+
+ pe = rn->info;
+
+ route_unlock_node(rn);
+
+ return pe;
}
/*
struct list *eigrp_neighbor_prefixes_lookup(struct eigrp *eigrp,
struct eigrp_neighbor *nbr)
{
- struct listnode *node1, *node11, *node2, *node22;
- struct eigrp_prefix_entry *prefix;
+ struct listnode *node2, *node22;
struct eigrp_nexthop_entry *entry;
+ struct eigrp_prefix_entry *pe;
+ struct route_node *rn;
/* create new empty list for prefixes storage */
struct list *prefixes = list_new();
/* iterate over all prefixes in topology table */
- for (ALL_LIST_ELEMENTS(eigrp->topology_table, node1, node11, prefix)) {
+ for (rn = route_top(eigrp->topology_table); rn; rn = route_next(rn)) {
+ if (!rn->info)
+ continue;
+ pe = rn->info;
/* iterate over all neighbor entry in prefix */
- for (ALL_LIST_ELEMENTS(prefix->entries, node2, node22, entry)) {
+ for (ALL_LIST_ELEMENTS(pe->entries, node2, node22, entry)) {
/* if entry is from specified neighbor, add to list */
if (entry->adv_router == nbr) {
- listnode_add(prefixes, prefix);
+ listnode_add(prefixes, pe);
}
}
}
void eigrp_topology_update_all_node_flags(struct eigrp *eigrp)
{
- struct list *table = eigrp->topology_table;
- struct eigrp_prefix_entry *data;
- struct listnode *node, *nnode;
- for (ALL_LIST_ELEMENTS(table, node, nnode, data)) {
- eigrp_topology_update_node_flags(data);
+ struct eigrp_prefix_entry *pe;
+ struct route_node *rn;
+
+ for (rn = route_top(eigrp->topology_table); rn; rn = route_next(rn)) {
+ pe = rn->info;
+
+ if (!pe)
+ continue;
+
+ eigrp_topology_update_node_flags(pe);
}
}
void eigrp_topology_neighbor_down(struct eigrp *eigrp,
struct eigrp_neighbor *nbr)
{
- struct listnode *node1, *node11, *node2, *node22;
- struct eigrp_prefix_entry *prefix;
+ struct listnode *node2, *node22;
+ struct eigrp_prefix_entry *pe;
struct eigrp_nexthop_entry *entry;
+ struct route_node *rn;
+
+ for (rn = route_top(eigrp->topology_table); rn; rn = route_next(rn)) {
+ pe = rn->info;
+
+ if (!pe)
+ continue;
- for (ALL_LIST_ELEMENTS(eigrp->topology_table, node1, node11, prefix)) {
- for (ALL_LIST_ELEMENTS(prefix->entries, node2, node22, entry)) {
+ for (ALL_LIST_ELEMENTS(pe->entries, node2, node22, entry)) {
struct eigrp_fsm_action_message msg;
if (entry->adv_router != nbr)
msg.data_type = EIGRP_INT;
msg.adv_router = nbr;
msg.entry = entry;
- msg.prefix = prefix;
+ msg.prefix = pe;
eigrp_fsm_event(&msg);
}
}
eigrp_update_send_all(eigrp, nbr->ei);
}
-void eigrp_update_topology_table_prefix(struct list *table,
+void eigrp_update_topology_table_prefix(struct route_table *table,
struct eigrp_prefix_entry *prefix)
{
struct listnode *node1, *node2;
#define _ZEBRA_EIGRP_TOPOLOGY_H
/* EIGRP Topology table related functions. */
-extern struct list *eigrp_topology_new(void);
-extern void eigrp_topology_init(struct list *);
+extern struct route_table *eigrp_topology_new(void);
+extern void eigrp_topology_init(struct route_table *table);
extern struct eigrp_prefix_entry *eigrp_prefix_entry_new(void);
extern struct eigrp_nexthop_entry *eigrp_nexthop_entry_new(void);
-extern void eigrp_topology_free(struct list *);
-extern void eigrp_topology_cleanup(struct list *);
-extern void eigrp_prefix_entry_add(struct list *, struct eigrp_prefix_entry *);
+extern void eigrp_topology_free(struct route_table *table);
+extern void eigrp_topology_cleanup(struct route_table *table);
+extern void eigrp_prefix_entry_add(struct route_table *table,
+ struct eigrp_prefix_entry *pe);
extern void eigrp_nexthop_entry_add(struct eigrp_prefix_entry *,
struct eigrp_nexthop_entry *);
-extern void eigrp_prefix_entry_delete(struct list *,
- struct eigrp_prefix_entry *);
+extern void eigrp_prefix_entry_delete(struct route_table *table,
+ struct eigrp_prefix_entry *pe);
extern void eigrp_nexthop_entry_delete(struct eigrp_prefix_entry *,
struct eigrp_nexthop_entry *);
-extern void eigrp_topology_delete_all(struct list *);
+extern void eigrp_topology_delete_all(struct route_table *table);
extern unsigned int eigrp_topology_table_isempty(struct list *);
extern struct eigrp_prefix_entry *
-eigrp_topology_table_lookup_ipv4(struct list *, struct prefix *);
+eigrp_topology_table_lookup_ipv4(struct route_table *table,
+ struct prefix *p);
extern struct list *eigrp_topology_get_successor(struct eigrp_prefix_entry *);
extern struct list *
eigrp_topology_get_successor_max(struct eigrp_prefix_entry *pe,
extern void eigrp_update_routing_table(struct eigrp_prefix_entry *);
extern void eigrp_topology_neighbor_down(struct eigrp *,
struct eigrp_neighbor *);
-extern void eigrp_update_topology_table_prefix(struct list *,
- struct eigrp_prefix_entry *);
+extern void eigrp_update_topology_table_prefix(struct route_table *table,
+ struct eigrp_prefix_entry *pe);
#endif
u_int16_t length = EIGRP_HEADER_LEN;
struct eigrp_nexthop_entry *te;
struct eigrp_prefix_entry *pe;
- struct listnode *node, *node2, *nnode, *nnode2;
+ struct listnode *node2, *nnode2;
struct eigrp_interface *ei = nbr->ei;
struct eigrp *eigrp = ei->eigrp;
struct prefix *dest_addr;
u_int32_t seq_no = eigrp->sequence_number;
+ u_int16_t mtu = ei->ifp->mtu;
+ struct route_node *rn;
- ep = eigrp_packet_new(ei->ifp->mtu, nbr);
+ ep = eigrp_packet_new(mtu, nbr);
/* Prepare EIGRP EOT UPDATE header */
eigrp_packet_header_init(EIGRP_OPC_UPDATE, eigrp,
length += eigrp_add_authTLV_MD5_to_stream(ep->s,ei);
}
- for (ALL_LIST_ELEMENTS(eigrp->topology_table, node, nnode, pe)) {
+ for (rn = route_top(eigrp->topology_table); rn; rn = route_next(rn)) {
+ if (!rn->info)
+ continue;
+
+ pe = rn->info;
for (ALL_LIST_ELEMENTS(pe->entries, node2, nnode2, te)) {
if (eigrp_nbr_split_horizon_check(te, ei))
continue;
- if ((length + 0x001D) > (u_int16_t)ei->ifp->mtu) {
+ if ((length + 0x001D) > mtu) {
eigrp_update_place_on_nbr_queue (nbr, ep, seq_no, length);
seq_no++;
length = EIGRP_HEADER_LEN;
- ep = eigrp_packet_new(ei->ifp->mtu, nbr);
- eigrp_packet_header_init(EIGRP_OPC_UPDATE, eigrp,
+ ep = eigrp_packet_new(mtu, nbr);
+ eigrp_packet_header_init(EIGRP_OPC_UPDATE,
+ nbr->ei->eigrp,
ep->s, EIGRP_EOT_FLAG,
- seq_no, nbr->recv_sequence_number);
+ seq_no,
+ nbr->recv_sequence_number);
if((ei->params.auth_type == EIGRP_AUTH_TYPE_MD5) &&
(ei->params.auth_keychain != NULL))
{
struct eigrp_packet *ep;
u_int16_t length = EIGRP_HEADER_LEN;
- struct listnode *node, *nnode;
struct eigrp_prefix_entry *pe;
struct prefix *dest_addr;
struct eigrp_interface *ei = nbr->ei;
struct list *prefixes;
u_int32_t flags;
unsigned int send_prefixes;
+ struct route_node *rn;
/* get prefixes to send to neighbor */
prefixes = nbr->nbr_gr_prefixes_send;
length += eigrp_add_authTLV_MD5_to_stream(ep->s, ei);
}
- for (ALL_LIST_ELEMENTS(eigrp->topology_table, node, nnode, pe)) {
+ for (rn = route_top(eigrp->topology_table); rn; rn = route_next(rn)) {
+ if (!rn->info)
+ continue;
+
+ pe = rn->info;
/*
* Filtering
*/
struct vty *vty)
{
struct eigrp_prefix_entry *pe2;
- struct listnode *node2, *nnode2;
struct list *prefixes;
+ struct route_node *rn;
+ struct eigrp_interface *ei = nbr->ei;
+ struct eigrp *eigrp = ei->eigrp;
if (gr_type == EIGRP_GR_FILTER) {
/* function was called after applying filtration */
zlog_info(
"Neighbor %s (%s) is resync: route configuration changed",
inet_ntoa(nbr->src),
- ifindex2ifname(nbr->ei->ifp->ifindex, VRF_DEFAULT));
+ ifindex2ifname(ei->ifp->ifindex, VRF_DEFAULT));
} else if (gr_type == EIGRP_GR_MANUAL) {
/* Graceful restart was called manually */
zlog_info("Neighbor %s (%s) is resync: manually cleared",
inet_ntoa(nbr->src),
- ifindex2ifname(nbr->ei->ifp->ifindex, VRF_DEFAULT));
+ ifindex2ifname(ei->ifp->ifindex, VRF_DEFAULT));
if (vty != NULL) {
vty_time_print(vty, 0);
vty_out(vty,
"Neighbor %s (%s) is resync: manually cleared\n",
inet_ntoa(nbr->src),
- ifindex2ifname(nbr->ei->ifp->ifindex,
+ ifindex2ifname(ei->ifp->ifindex,
VRF_DEFAULT));
}
}
prefixes = list_new();
/* add all prefixes from topology table to list */
- for (ALL_LIST_ELEMENTS(nbr->ei->eigrp->topology_table, node2, nnode2,
- pe2)) {
+ for (rn = route_top(eigrp->topology_table); rn; rn = route_next(rn)) {
+ if (!rn->info)
+ continue;
+
+ pe2 = rn->info;
listnode_add(prefixes, pe2);
}
struct prefix p;
int ret;
- str2prefix(argv[1]->arg, &p);
+ (void)str2prefix(argv[1]->arg, &p);
ret = eigrp_network_set(eigrp, &p);
struct prefix p;
int ret;
- str2prefix(argv[2]->arg, &p);
+ (void)str2prefix(argv[2]->arg, &p);
ret = eigrp_network_unset(eigrp, &p);
"Show all links in topology table\n")
{
struct eigrp *eigrp;
- struct listnode *node, *node2;
+ struct listnode *node;
struct eigrp_prefix_entry *tn;
struct eigrp_nexthop_entry *te;
+ struct route_node *rn;
int first;
eigrp = eigrp_lookup();
show_ip_eigrp_topology_header(vty, eigrp);
- for (ALL_LIST_ELEMENTS_RO(eigrp->topology_table, node, tn)) {
+ for (rn = route_top(eigrp->topology_table); rn; rn = route_next(rn)) {
+ if (!rn->info)
+ continue;
+
+ tn = rn->info;
first = 1;
- for (ALL_LIST_ELEMENTS_RO(tn->entries, node2, te)) {
+ for (ALL_LIST_ELEMENTS_RO(tn->entries, node, te)) {
if (argc == 5
|| (((te->flags
& EIGRP_NEXTHOP_ENTRY_SUCCESSOR_FLAG)
DEFUN (no_eigrp_if_ip_holdinterval,
no_eigrp_if_ip_holdinterval_cmd,
"no ip hold-time eigrp",
- "No"
+ NO_STR
"Interface Internet Protocol config commands\n"
"Configures EIGRP hello interval\n"
- "Enhanced Interior Gateway Routing Protocol (EIGRP)\n"
- "Seconds before neighbor is considered down\n")
+ "Enhanced Interior Gateway Routing Protocol (EIGRP)\n")
{
VTY_DECLVAR_CONTEXT(interface, ifp);
struct eigrp_interface *ei = ifp->info;
{
zclient = zclient_new(master);
- zclient_init(zclient, ZEBRA_ROUTE_EIGRP, 0);
+ zclient_init(zclient, ZEBRA_ROUTE_EIGRP, 0, &eigrpd_privs);
zclient->zebra_connected = eigrp_zebra_connected;
zclient->router_id_update = eigrp_router_id_update_zebra;
zclient->interface_add = eigrp_interface_add;
/* init internal data structures */
eigrp->eiflist = list_new();
eigrp->passive_interface_default = EIGRP_IF_ACTIVE;
- eigrp->networks = route_table_init();
+ eigrp->networks = eigrp_topology_new();
if ((eigrp_socket = eigrp_sock_init()) < 0) {
zlog_err(
thread_add_read(master, eigrp_read, eigrp, eigrp->fd, &eigrp->t_read);
eigrp->oi_write_q = list_new();
- eigrp->topology_table = eigrp_topology_new();
+ eigrp->topology_table = route_table_init();
eigrp->neighbor_self = eigrp_nbr_new(NULL);
eigrp->neighbor_self->src.s_addr = INADDR_ANY;
extern struct zclient *zclient;
extern struct thread_master *master;
extern struct eigrp_master *eigrp_om;
+extern struct zebra_privs_t eigrpd_privs;
/* Prototypes */
extern void eigrp_master_init(void);
#include "privs.h"
-extern struct zebra_privs_t isisd_privs;
-
struct bpf_insn llcfilter[] = {
/* check first byte */
BPF_STMT(BPF_LD + BPF_B + BPF_ABS, ETH_ALEN),
circuit->lsp_queue = list_new();
circuit->lsp_hash = isis_lsp_hash_new();
- monotime(&circuit->lsp_queue_last_cleared);
+ circuit->lsp_queue_last_push = monotime(NULL);
return ISIS_OK;
}
struct thread *t_send_lsp;
struct list *lsp_queue; /* LSPs to be txed (both levels) */
struct isis_lsp_hash *lsp_hash; /* Hashtable synchronized with lsp_queue */
- struct timeval lsp_queue_last_cleared; /* timestamp used to enforce transmit
+ time_t lsp_queue_last_push; /* timestamp used to enforce transmit
* interval;
* for scalability, use one timestamp per
* circuit, instead of one per lsp per
#define MAX_MIN_LSP_GEN_INTERVAL 120 /* RFC 4444 says 65535 */
#define DEFAULT_MIN_LSP_GEN_INTERVAL 30
-#define MIN_LSP_TRANS_INTERVAL 20000 /* Microseconds */
+#define MIN_LSP_RETRANS_INTERVAL 5 /* Seconds */
#define MIN_CSNP_INTERVAL 1
#define MAX_CSNP_INTERVAL 600
#include "privs.h"
-extern struct zebra_privs_t isisd_privs;
-
static t_uscalar_t dlpi_ctl[1024]; /* DLPI control messages */
/*
struct isis_tlvs *tlvs, struct stream *stream,
struct isis_area *area, int level, bool confusion)
{
- dnode_t *dnode = NULL;
-
- /* Remove old LSP from database. This is required since the
- * lsp_update_data will free the lsp->pdu (which has the key, lsp_id)
- * and will update it with the new data in the stream.
- * XXX: This doesn't hold true anymore since the header is now a copy.
- * keeping the LSP in the dict if it is already present should be possible */
- dnode = dict_lookup(area->lspdb[level - 1], lsp->hdr.lsp_id);
- if (dnode)
- dnode_destroy(dict_delete(area->lspdb[level - 1], dnode));
-
if (lsp->own_lsp) {
zlog_err(
"ISIS-Upd (%s): BUG updating LSP %s still marked as own LSP",
lsp_link_fragment(lsp, lsp0);
}
- /* insert the lsp back into the database */
- lsp_insert(lsp, area->lspdb[level - 1]);
+ if (lsp->hdr.seqno)
+ isis_spf_schedule(lsp->area, lsp->level);
}
/* creation of LSP directly from what we received */
dnode_t *dnode, *dnode_next;
int level;
u_int16_t rem_lifetime;
+ time_t now = monotime(NULL);
lsp_list = list_new();
if (!circuit->lsp_queue)
continue;
- if (monotime_since(
- &circuit->lsp_queue_last_cleared,
- NULL) < MIN_LSP_TRANS_INTERVAL) {
+ if (now - circuit->lsp_queue_last_push
+ < MIN_LSP_RETRANS_INTERVAL) {
continue;
}
+ circuit->lsp_queue_last_push = now;
+
for (ALL_LIST_ELEMENTS_RO(
lsp_list, lspnode, lsp)) {
if (circuit->upadjcount
lsp = isis_circuit_lsp_queue_pop(circuit);
if (!lsp)
return ISIS_OK;
- /* Set the last-cleared time if the queue is empty. */
- /* TODO: Is is possible that new lsps keep being added to the queue
- * that the queue is never empty? */
- if (list_isempty(circuit->lsp_queue)) {
- monotime(&circuit->lsp_queue_last_cleared);
- } else {
+
+ if (!list_isempty(circuit->lsp_queue)) {
isis_circuit_schedule_lsp_send(circuit);
}
#include "privs.h"
-extern struct zebra_privs_t isisd_privs;
-
/* tcpdump -i eth0 'isis' -dd */
static struct sock_filter isisfilter[] =
{
void isis_zebra_init(struct thread_master *master)
{
zclient = zclient_new(master);
- zclient_init(zclient, ZEBRA_ROUTE_ISIS, 0);
+ zclient_init(zclient, ZEBRA_ROUTE_ISIS, 0, &isisd_privs);
zclient->zebra_connected = isis_zebra_connected;
zclient->router_id_update = isis_router_id_update_zebra;
zclient->interface_add = isis_zebra_if_add;
"router isis WORD",
ROUTER_STR
"ISO IS-IS\n"
- "ISO Routing area tag")
+ "ISO Routing area tag\n")
{
int idx_word = 2;
return isis_area_get(vty, argv[idx_word]->arg);
#include "isis_memory.h"
#include "qobj.h"
+extern struct zebra_privs_t isisd_privs;
+
/* uncomment if you are a developer in bug hunt */
/* #define EXTREME_DEBUG */
/* #define EXTREME_DICT_DEBUG */
/* lde privileges */
static zebra_capabilities_t _caps_p [] =
{
- /* none */
+ ZCAP_NET_ADMIN
};
static struct zebra_privs_t lde_privs =
zclient_sync->sock = -1;
zclient_sync->redist_default = ZEBRA_ROUTE_LDP;
zclient_sync->instance = instance;
+ zclient_sync->privs = &lde_privs;
+
while (zclient_socket_connect(zclient_sync) < 0) {
log_warnx("Error connecting synchronous zclient!");
sleep(1);
ZEBRA_ROUTE_ALL, 0, VRF_DEFAULT);
}
+extern struct zebra_privs_t ldpd_privs;
+
void
ldp_zebra_init(struct thread_master *master)
{
/* Set default values. */
zclient = zclient_new(master);
- zclient_init(zclient, ZEBRA_ROUTE_LDP, 0);
+ zclient_init(zclient, ZEBRA_ROUTE_LDP, 0, &ldpd_privs);
/* set callbacks */
zclient->zebra_connected = ldp_zebra_connected;
ssize_t nbytes;
#if 0
- /* Should we attempt to drain any previously buffered data? This could help
- reduce latency in pushing out the data if we are stuck in a long-running
- thread that is preventing the main select loop from calling the flush
- thread... */
- if (b->head && (buffer_flush_available(b, fd) == BUFFER_ERROR))
- return BUFFER_ERROR;
+ /*
+ * Should we attempt to drain any previously buffered data?
+ * This could help reduce latency in pushing out the data if
+ * we are stuck in a long-running thread that is preventing
+ * the main select loop from calling the flush thread...
+ */
+ if (b->head && (buffer_flush_available(b, fd) == BUFFER_ERROR))
+ return BUFFER_ERROR;
#endif
if (b->head)
/* Buffer is not empty, so do not attempt to write the new data.
DEFUN (config_end,
config_end_cmd,
"end",
- "End current mode and change to enable mode.")
+ "End current mode and change to enable mode.\n")
{
switch (vty->node) {
case VIEW_NODE:
pthread_mutex_lock(&_hashes_mtx);
if (!_hashes) {
pthread_mutex_unlock(&_hashes_mtx);
+ ttable_del(tt);
vty_out(vty, "No hash tables in use.\n");
return CMD_SUCCESS;
}
/* Delete and free interface structure. */
void if_delete(struct interface *ifp)
{
- struct vrf *vrf = vrf_lookup_by_id(ifp->vrf_id);
+ struct vrf *vrf;
+
+ vrf = vrf_lookup_by_id(ifp->vrf_id);
+ assert(vrf);
IFNAME_RB_REMOVE(vrf, ifp);
if (ifp->ifindex != IFINDEX_INTERNAL)
/* Interface existance check by index. */
struct interface *if_lookup_by_index(ifindex_t ifindex, vrf_id_t vrf_id)
{
- struct vrf *vrf = vrf_lookup_by_id(vrf_id);
+ struct vrf *vrf;
struct interface if_tmp;
+ vrf = vrf_lookup_by_id(vrf_id);
+ if (!vrf)
+ return NULL;
+
if_tmp.ifindex = ifindex;
return RB_FIND(if_index_head, &vrf->ifaces_by_index, &if_tmp);
}
struct vrf *vrf = vrf_lookup_by_id(vrf_id);
struct interface if_tmp;
- if (!name || strnlen(name, INTERFACE_NAMSIZ) == INTERFACE_NAMSIZ)
+ if (!vrf || !name
+ || strnlen(name, INTERFACE_NAMSIZ) == INTERFACE_NAMSIZ)
return NULL;
strlcpy(if_tmp.name, name, sizeof(if_tmp.name));
void if_set_index(struct interface *ifp, ifindex_t ifindex)
{
- struct vrf *vrf = vrf_lookup_by_id(ifp->vrf_id);
+ struct vrf *vrf;
+
+ vrf = vrf_lookup_by_id(ifp->vrf_id);
+ assert(vrf);
if (ifp->ifindex == ifindex)
return;
"Day of th month to start\n"
"Month of the year to start\n"
"Year to start\n"
- "Never expires")
+ "Never expires\n")
{
int idx_hhmmss = 1;
int idx_number = 2;
"Month of the year to start\n"
"Day of th month to start\n"
"Year to start\n"
- "Never expires")
+ "Never expires\n")
{
int idx_hhmmss = 1;
int idx_month = 2;
"Day of th month to start\n"
"Month of the year to start\n"
"Year to start\n"
- "Never expires")
+ "Never expires\n")
{
int idx_hhmmss = 1;
int idx_number = 2;
"Month of the year to start\n"
"Day of th month to start\n"
"Year to start\n"
- "Never expires")
+ "Never expires\n")
{
int idx_hhmmss = 1;
int idx_month = 2;
return ret;
}
-/* sockunion_connect returns
- -1 : error occured
- 0 : connect success
- 1 : connect is in progress */
+/* Performs a non-blocking connect(). */
enum connect_result sockunion_connect(int fd, const union sockunion *peersu,
unsigned short port, ifindex_t ifindex)
{
int ret;
- int val;
union sockunion su;
memcpy(&su, peersu, sizeof(union sockunion));
break;
}
- /* Make socket non-block. */
- val = fcntl(fd, F_GETFL, 0);
- fcntl(fd, F_SETFL, val | O_NONBLOCK);
-
/* Call connect function. */
ret = connect(fd, (struct sockaddr *)&su, sockunion_sizeof(&su));
/* Immediate success */
- if (ret == 0) {
- fcntl(fd, F_SETFL, val);
+ if (ret == 0)
return connect_success;
- }
/* If connect is in progress then return 1 else it's real error. */
if (ret < 0) {
}
}
- fcntl(fd, F_SETFL, val);
-
return connect_in_progress;
}
#include "table.h"
#include "nexthop.h"
#include "mpls.h"
+#include "sockopt.h"
DEFINE_MTYPE_STATIC(LIB, ZCLIENT, "Zclient")
DEFINE_MTYPE_STATIC(LIB, REDIST_INST, "Redistribution instance IDs")
&zclient->mi_redist[afi][zclient->redist_default],
zclient->instance);
- zclient_init(zclient, zclient->redist_default, zclient->instance);
+ zclient_init(zclient, zclient->redist_default,
+ zclient->instance, zclient->privs);
}
/**
set_cloexec(sock);
+ zclient->privs->change(ZPRIVS_RAISE);
+ setsockopt_so_sendbuf(sock, 1048576);
+ zclient->privs->change(ZPRIVS_LOWER);
+
/* Connect to zebra. */
ret = connect(sock, (struct sockaddr *)&zclient_addr,
zclient_addr_len);
/* Initialize zebra client. Argument redist_default is unwanted
redistribute route type. */
-void zclient_init(struct zclient *zclient, int redist_default, u_short instance)
+void zclient_init(struct zclient *zclient, int redist_default,
+ u_short instance, struct zebra_privs_t *privs)
{
int afi, i;
/* Set -1 to the default socket value. */
zclient->sock = -1;
+ zclient->privs = privs;
/* Clear redistribution flags. */
for (afi = AFI_IP; afi < AFI_MAX; afi++)
/* The thread master we schedule ourselves on */
struct thread_master *master;
+ /* Priviledges to change socket values */
+ struct zebra_privs_t *privs;
+
/* Socket to zebra daemon. */
int sock;
/* Prototypes of zebra client service functions. */
extern struct zclient *zclient_new(struct thread_master *);
-extern void zclient_init(struct zclient *, int, u_short);
+extern void zclient_init(struct zclient *, int, u_short, struct zebra_privs_t *privs);
extern int zclient_start(struct zclient *);
extern void zclient_stop(struct zclient *);
extern void zclient_reset(struct zclient *);
ZCAP_DAC_OVERRIDE, /* for now needed to write to /proc/sys/net/ipv4/<if>/send_redirect */
};
-static struct zebra_privs_t nhrpd_privs = {
+struct zebra_privs_t nhrpd_privs = {
#if defined(FRR_USER) && defined(FRR_GROUP)
.user = FRR_USER,
.group = FRR_GROUP,
zclient->redistribute_route_add = nhrp_route_read;
zclient->redistribute_route_del = nhrp_route_read;
- zclient_init(zclient, ZEBRA_ROUTE_NHRP, 0);
+ zclient_init(zclient, ZEBRA_ROUTE_NHRP, 0, &nhrpd_privs);
}
void nhrp_zebra_terminate(void)
NHRP_STR
"Configure NHRP advertised MTU\n"
"MTU value\n"
- "Advertise bound interface MTU similar to OpenNHRP")
+ "Advertise bound interface MTU similar to OpenNHRP\n")
{
VTY_DECLVAR_CONTEXT(interface, ifp);
struct nhrp_interface *nifp = ifp->info;
NHRP_STR
"Configure NHRP advertised MTU\n"
"MTU value\n"
- "Advertise bound interface MTU similar to OpenNHRP")
+ "Advertise bound interface MTU similar to OpenNHRP\n")
{
VTY_DECLVAR_CONTEXT(interface, ifp);
struct nhrp_interface *nifp = ifp->info;
} afi[AFI_MAX];
};
+extern struct zebra_privs_t nhrpd_privs;
+
int sock_open_unix(const char *path);
void nhrp_interface_init(void);
#include "libospf.h"
#include "ospf6_proto.h"
#include "ospf6_network.h"
-
-extern struct zebra_privs_t ospf6d_privs;
+#include "ospf6d.h"
int ospf6_sock;
struct in6_addr allspfrouters6;
{
/* Allocate zebra structure. */
zclient = zclient_new(master);
- zclient_init(zclient, ZEBRA_ROUTE_OSPF6, 0);
+ zclient_init(zclient, ZEBRA_ROUTE_OSPF6, 0, &ospf6d_privs);
zclient->zebra_connected = ospf6_zebra_connected;
zclient->router_id_update = ospf6_router_id_update_zebra;
zclient->interface_add = ospf6_zebra_if_add;
return CMD_SUCCESS; \
}
+extern struct zebra_privs_t ospf6d_privs;
/* Function Prototypes */
extern struct route_node *route_prev(struct route_node *node);
return match;
}
+static void ospf_if_reset_stats(struct ospf_interface *oi)
+{
+ oi->hello_in = oi->hello_out = 0;
+ oi->db_desc_in = oi->db_desc_out = 0;
+ oi->ls_req_in = oi->ls_req_out = 0;
+ oi->ls_upd_in = oi->ls_upd_out = 0;
+ oi->ls_ack_in = oi->ls_ack_out = 0;
+}
+
void ospf_if_stream_set(struct ospf_interface *oi)
{
/* set output fifo queue. */
ospf_fifo_free(oi->obuf);
oi->obuf = NULL;
+ /*reset protocol stats */
+ ospf_if_reset_stats(oi);
+
if (oi->on_write_q) {
listnode_delete(ospf->oi_write_q, oi);
if (list_isempty(ospf->oi_write_q))
if (lsa != NULL && (lsah = lsa->data) != NULL) {
char id[INET_ADDRSTRLEN], ar[INET_ADDRSTRLEN];
- strcpy(id, inet_ntoa(lsah->id));
- strcpy(ar, inet_ntoa(lsah->adv_router));
+ strlcpy(id, inet_ntoa(lsah->id), sizeof(id));
+ strlcpy(ar, inet_ntoa(lsah->adv_router), sizeof(ar));
sprintf(buf, "Type%d,id(%s),ar(%s)", lsah->type, id, ar);
} else
- strcpy(buf, "NULL");
+ strlcpy(buf, "NULL", sizeof(buf));
return buf;
}
new->data->type, NULL));
break;
default:
- strcpy(area_str, inet_ntoa(new->area->area_id));
+ strlcpy(area_str, inet_ntoa(new->area->area_id),
+ sizeof(area_str));
zlog_debug("LSA[%s]: Install %s to Area %s",
dump_lsa_key(new),
lookup_msg(ospf_lsa_type_msg,
#include "sockopt.h"
#include "privs.h"
-extern struct zebra_privs_t ospfd_privs;
-
#include "ospfd/ospfd.h"
#include "ospfd/ospf_network.h"
#include "ospfd/ospf_interface.h"
"-----------------------------------------------------");
}
+ switch (type) {
+ case OSPF_MSG_HELLO:
+ oi->hello_out++;
+ break;
+ case OSPF_MSG_DB_DESC:
+ oi->db_desc_out++;
+ break;
+ case OSPF_MSG_LS_REQ:
+ oi->ls_req_out++;
+ break;
+ case OSPF_MSG_LS_UPD:
+ oi->ls_upd_out++;
+ break;
+ case OSPF_MSG_LS_ACK:
+ oi->ls_ack_out++;
+ break;
+ default:
+ break;
+ }
+
/* Now delete packet from queue. */
ospf_packet_delete(oi);
OSPF_RI_STR
"Enable the Router Information functionality with AS flooding scope\n"
"Enable the Router Information functionality with Area flooding scope\n"
- "OSPF area ID in IP format")
+ "OSPF area ID in IP format\n")
{
int idx_ipv4 = 2;
char *area = (argc == 3) ? argv[idx_ipv4]->arg : NULL;
if (IS_DEBUG_OSPF(lsa, LSA_GENERATE)) {
char area_id[INET_ADDRSTRLEN];
- strcpy(area_id, inet_ntoa(area->area_id));
+ strlcpy(area_id, inet_ntoa(area->area_id), sizeof(area_id));
zlog_debug(
"LSA[Type%d:%s]: Originate Opaque-LSA/MPLS-TE: Area(%s), Link(%s)",
new->data->type, inet_ntoa(new->data->id), area_id,
return CMD_SUCCESS;
}
+static void show_ip_ospf_interface_traffic_sub(struct vty *vty,
+ struct ospf_interface *oi,
+ json_object *json_interface_sub,
+ u_char use_json)
+{
+ if (use_json) {
+ json_object_int_add(json_interface_sub,
+ "ifIndex",
+ oi->ifp->ifindex);
+ json_object_int_add(json_interface_sub,
+ "helloIn",
+ oi->hello_in);
+ json_object_int_add(json_interface_sub,
+ "helloOut",
+ oi->hello_out);
+ json_object_int_add(json_interface_sub,
+ "dbDescIn",
+ oi->db_desc_in);
+ json_object_int_add(json_interface_sub,
+ "dbDescOut",
+ oi->db_desc_out);
+ json_object_int_add(json_interface_sub,
+ "lsReqIn",
+ oi->ls_req_in);
+ json_object_int_add(json_interface_sub,
+ "lsReqOut",
+ oi->ls_req_out);
+ json_object_int_add(json_interface_sub,
+ "lsUpdIn",
+ oi->ls_upd_in);
+ json_object_int_add(json_interface_sub,
+ "lsUpdOut",
+ oi->ls_upd_out);
+ json_object_int_add(json_interface_sub,
+ "lsAckIn",
+ oi->ls_ack_in);
+ json_object_int_add(json_interface_sub,
+ "lsAckOut",
+ oi->ls_ack_out);
+ } else {
+ vty_out(vty,
+ "%-10s %8u/%-8u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u\n",
+ oi->ifp->name, oi->hello_in,
+ oi->hello_out,
+ oi->db_desc_in, oi->db_desc_out,
+ oi->ls_req_in, oi->ls_req_out,
+ oi->ls_upd_in, oi->ls_upd_out,
+ oi->ls_ack_in, oi->ls_ack_out);
+ }
+}
+
+/* OSPFv2 Packet Counters */
+static int show_ip_ospf_interface_traffic_common(struct vty *vty,
+ struct ospf *ospf,
+ char *intf_name,
+ int display_once,
+ u_char use_json)
+{
+ struct vrf *vrf = NULL;
+ struct interface *ifp = NULL;
+ json_object *json = NULL;
+ json_object *json_interface_sub = NULL;
+
+ if (!use_json && !display_once) {
+ vty_out(vty, "\n");
+ vty_out(vty, "%-12s%-17s%-17s%-17s%-17s%-17s\n",
+ "Interface", " HELLO", " DB-Desc", " LS-Req",
+ " LS-Update", " LS-Ack");
+ vty_out(vty, "%-10s%-18s%-18s%-17s%-17s%-17s\n", "",
+ " Rx/Tx", " Rx/Tx", " Rx/Tx", " Rx/Tx", " Rx/Tx");
+ vty_out(vty,
+ "--------------------------------------------------------------------------------------------\n");
+ } else if (use_json) {
+ json = json_object_new_object();
+ }
+
+ if (intf_name == NULL) {
+ vrf = vrf_lookup_by_id(ospf->vrf_id);
+ FOR_ALL_INTERFACES (vrf, ifp) {
+ struct route_node *rn;
+ struct ospf_interface *oi;
+
+ if (ospf_oi_count(ifp) == 0)
+ continue;
+
+ for (rn = route_top(IF_OIFS(ifp)); rn;
+ rn = route_next(rn)) {
+ oi = rn->info;
+
+ if (oi == NULL)
+ continue;
+
+ if (use_json) {
+ json_interface_sub =
+ json_object_new_object();
+ }
+
+ show_ip_ospf_interface_traffic_sub(vty, oi,
+ json_interface_sub,
+ use_json);
+ if (use_json) {
+ json_object_object_add(json, ifp->name,
+ json_interface_sub);
+ }
+ }
+ }
+ } else {
+ /* Interface name is specified. */
+ ifp = if_lookup_by_name(intf_name, ospf->vrf_id);
+ if (ifp != NULL) {
+ struct route_node *rn;
+ struct ospf_interface *oi;
+
+ if (ospf_oi_count(ifp) == 0) {
+ vty_out(vty, " OSPF not enabled on this interface %s\n",
+ ifp->name);
+ return CMD_SUCCESS;
+ }
+
+ for (rn = route_top(IF_OIFS(ifp)); rn;
+ rn = route_next(rn)) {
+ oi = rn->info;
+
+ if (use_json) {
+ json_interface_sub =
+ json_object_new_object();
+ }
+
+ show_ip_ospf_interface_traffic_sub(vty, oi,
+ json_interface_sub,
+ use_json);
+ if (use_json) {
+ json_object_object_add(json, ifp->name,
+ json_interface_sub);
+ }
+ }
+ }
+ }
+
+ if (use_json) {
+ vty_out(vty, "%s\n", json_object_to_json_string_ext(
+ json, JSON_C_TO_STRING_PRETTY));
+ json_object_free(json);
+ }
+
+ return CMD_SUCCESS;
+}
+
DEFUN (show_ip_ospf_interface,
show_ip_ospf_interface_cmd,
"show ip ospf [vrf <NAME|all>] interface [INTERFACE] [json]",
return show_ip_ospf_interface_common(vty, ospf, argc, argv, 5, uj);
}
+DEFUN (show_ip_ospf_interface_traffic,
+ show_ip_ospf_interface_traffic_cmd,
+ "show ip ospf [vrf <NAME|all>] interface traffic [INTERFACE] [json]",
+ SHOW_STR
+ IP_STR
+ "OSPF information\n"
+ VRF_CMD_HELP_STR
+ "All VRFs\n"
+ "Interface information\n"
+ "Protocol Packet counters\n"
+ "Interface name\n"
+ JSON_STR)
+{
+ struct ospf *ospf = NULL;
+ struct listnode *node = NULL;
+ char *vrf_name = NULL, *intf_name = NULL;
+ bool all_vrf = FALSE;
+ int inst = 0;
+ int idx_vrf = 0, idx_intf = 0;
+ u_char uj = use_json(argc, argv);
+ int ret = CMD_SUCCESS;
+ int display_once = 0;
+
+ if (uj)
+ argc--;
+
+
+ OSPF_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
+
+ if (argv_find(argv, argc, "INTERFACE", &idx_intf))
+ intf_name = argv[idx_intf]->arg;
+
+ if (vrf_name) {
+ if (all_vrf) {
+ for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) {
+ if (!ospf->oi_running)
+ continue;
+
+ ret = show_ip_ospf_interface_traffic_common(vty,
+ ospf, intf_name,
+ display_once,
+ uj);
+ display_once = 1;
+ }
+ return ret;
+ }
+ ospf = ospf_lookup_by_inst_name(inst, vrf_name);
+ if (ospf == NULL || !ospf->oi_running)
+ return CMD_SUCCESS;
+ ret = show_ip_ospf_interface_traffic_common(vty, ospf,
+ intf_name,
+ display_once, uj);
+ } else {
+ ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
+ if (ospf == NULL || !ospf->oi_running)
+ return CMD_SUCCESS;
+ ret = show_ip_ospf_interface_traffic_common(vty, ospf,
+ intf_name,
+ display_once, uj);
+ }
+
+ return ret;
+}
+
+
static void show_ip_ospf_neighbour_header(struct vty *vty)
{
vty_out(vty, "\n%-15s %3s %-15s %9s %-15s %-20s %5s %5s %5s\n",
"IP Information\n"
"OSPF interface commands\n"
"Enable authentication on this interface\n"
- "Address of interface")
+ "Address of interface\n")
{
VTY_DECLVAR_CONTEXT(interface, ifp);
int idx_ipv4 = 3;
"Enable authentication on this interface\n"
"Use null authentication\n"
"Use message-digest authentication\n"
- "Address of interface")
+ "Address of interface\n")
{
VTY_DECLVAR_CONTEXT(interface, ifp);
int idx_encryption = 4;
"IP Information\n"
"OSPF interface commands\n"
"Enable authentication on this interface\n"
- "Address of interface")
+ "Address of interface\n")
{
VTY_DECLVAR_CONTEXT(interface, ifp);
int idx_ipv4 = 4;
"OSPF interface commands\n"
"Authentication password (key)\n"
"The OSPF password (key)\n"
- "Address of interface")
+ "Address of interface\n")
{
VTY_DECLVAR_CONTEXT(interface, ifp);
int idx = 0;
"OSPF interface commands\n"
"Message digest authentication password (key)\n"
"Key ID\n"
- "Address of interface")
+ "Use MD5 algorithm\n"
+ "The OSPF password (key)\n"
+ "Address of interface\n")
{
return no_ip_ospf_message_digest_key(self, vty, argc, argv);
}
no_ip_ospf_cost_cmd,
"no ip ospf cost [(1-65535)] [A.B.C.D]",
NO_STR
+ "IP Information\n"
"OSPF interface commands\n"
"Interface cost\n"
- "Address of interface")
+ "Cost\n"
+ "Address of interface\n")
{
VTY_DECLVAR_CONTEXT(interface, ifp);
int idx = 0;
"OSPF interface commands\n"
"Interval time after which a neighbor is declared down\n"
"Seconds\n"
- "Address of interface")
+ "Minimal 1s dead-interval with fast sub-second hellos\n"
+ "Hello multiplier factor\n"
+ "Number of Hellos to send each second\n"
+ "Address of interface\n")
{
VTY_DECLVAR_CONTEXT(interface, ifp);
int idx_ipv4 = argc - 1;
"OSPF interface commands\n"
"Interval time after which a neighbor is declared down\n"
"Seconds\n"
- "Address of interface")
+ "Minimal 1s dead-interval with fast sub-second hellos\n"
+ "Hello multiplier factor\n"
+ "Number of Hellos to send each second\n"
+ "Address of interface\n")
{
return no_ip_ospf_dead_interval(self, vty, argc, argv);
}
"OSPF interface commands\n"
"Router priority\n"
"Priority\n"
- "Address of interface")
+ "Address of interface\n")
{
VTY_DECLVAR_CONTEXT(interface, ifp);
int idx = 0;
"OSPF interface commands\n"
"Router priority\n"
"Priority\n"
- "Address of interface")
+ "Address of interface\n")
{
return ip_ospf_priority(self, vty, argc, argv);
}
"OSPF interface commands\n"
"Router priority\n" // ignored
"Priority\n"
- "Address of interface")
+ "Address of interface\n")
{
VTY_DECLVAR_CONTEXT(interface, ifp);
int idx = 0;
"OSPF interface commands\n"
"Router priority\n"
"Priority\n"
- "Address of interface")
+ "Address of interface\n")
{
return no_ip_ospf_priority(self, vty, argc, argv);
}
"OSPF interface commands\n"
"Time between retransmitting lost link state advertisements\n"
"Seconds\n"
- "Address of interface")
+ "Address of interface\n")
{
VTY_DECLVAR_CONTEXT(interface, ifp);
int idx = 0;
"OSPF interface commands\n"
"Time between retransmitting lost link state advertisements\n"
"Seconds\n"
- "Address of interface")
+ "Address of interface\n")
{
return ip_ospf_retransmit_interval(self, vty, argc, argv);
}
"OSPF interface commands\n"
"Link state transmit delay\n"
"Seconds\n"
- "Address of interface")
+ "Address of interface\n")
{
VTY_DECLVAR_CONTEXT(interface, ifp);
int idx = 0;
"OSPF interface commands\n"
"Link state transmit delay\n"
"Seconds\n"
- "Address of interface")
+ "Address of interface\n")
{
return ip_ospf_transmit_delay(self, vty, argc, argv);
}
"IP Information\n"
"OSPF interface commands\n"
"Link state transmit delay\n"
- "Address of interface")
+ "Seconds\n"
+ "Address of interface\n")
{
VTY_DECLVAR_CONTEXT(interface, ifp);
int idx = 0;
"OSPF interface commands\n"
"Link state transmit delay\n"
"Seconds\n"
- "Address of interface")
+ "Address of interface\n")
{
return no_ip_ospf_transmit_delay(self, vty, argc, argv);
}
"IP Information\n"
"OSPF interface commands\n"
"Disable MTU mismatch detection on this interface\n"
- "Address of interface")
+ "Address of interface\n")
{
VTY_DECLVAR_CONTEXT(interface, ifp);
int idx_ipv4 = 3;
DEFUN (no_ip_ospf_mtu_ignore,
no_ip_ospf_mtu_ignore_addr_cmd,
"no ip ospf mtu-ignore [A.B.C.D]",
+ NO_STR
"IP Information\n"
"OSPF interface commands\n"
"Disable MTU mismatch detection on this interface\n"
- "Address of interface")
+ "Address of interface\n")
{
VTY_DECLVAR_CONTEXT(interface, ifp);
int idx_ipv4 = 4;
install_element(VIEW_NODE, &show_ip_ospf_interface_cmd);
install_element(VIEW_NODE, &show_ip_ospf_instance_interface_cmd);
+ /* "show ip ospf interface traffic */
+ install_element(VIEW_NODE, &show_ip_ospf_interface_traffic_cmd);
/* "show ip ospf neighbor" commands. */
install_element(VIEW_NODE, &show_ip_ospf_neighbor_int_detail_cmd);
{
/* Allocate zebra structure. */
zclient = zclient_new(master);
- zclient_init(zclient, ZEBRA_ROUTE_OSPF, instance);
+ zclient_init(zclient, ZEBRA_ROUTE_OSPF, instance, &ospfd_privs);
zclient->zebra_connected = ospf_zebra_connected;
zclient->router_id_update = ospf_router_id_update_zebra;
zclient->interface_add = ospf_interface_add;
extern struct zclient *zclient;
extern struct in_addr router_id_zebra;
-extern struct zebra_privs_t ospfd_privs;
static void ospf_remove_vls_through_area(struct ospf *, struct ospf_area *);
extern struct zclient *zclient;
extern struct thread_master *master;
extern int ospf_zlog;
+extern struct zebra_privs_t ospfd_privs;
/* Prototypes. */
extern const char *ospf_redist_string(u_int route_type);
zclient->interface_address_delete = pim_zebra_if_address_del;
zclient->nexthop_update = pim_parse_nexthop_update;
- zclient_init(zclient, ZEBRA_ROUTE_PIM, 0);
+ zclient_init(zclient, ZEBRA_ROUTE_PIM, 0, &pimd_privs);
if (PIM_DEBUG_PIM_TRACE) {
zlog_info("zclient_init cleared redistribution request");
}
zlookup->sock = -1;
zlookup->t_connect = NULL;
+ zlookup->privs = &pimd_privs;
zclient_lookup_sched_now(zlookup);
{RI_RIP_VERSION_NONE, "none"},
{0}};
-extern struct zebra_privs_t ripd_privs;
-
/* RIP enabled network vector. */
vector rip_enable_interface;
{
/* Set default value to the zebra client structure. */
zclient = zclient_new(master);
- zclient_init(zclient, ZEBRA_ROUTE_RIP, 0);
+ zclient_init(zclient, ZEBRA_ROUTE_RIP, 0, &ripd_privs);
zclient->zebra_connected = rip_zebra_connected;
zclient->interface_add = rip_interface_add;
zclient->interface_delete = rip_interface_delete;
/* UDP receive buffer size */
#define RIP_UDP_RCV_BUF 41600
-/* privileges global */
-extern struct zebra_privs_t ripd_privs;
-
/* RIP Structure. */
struct rip *rip = NULL;
/* There is only one rip strucutre. */
extern struct rip *rip;
+extern struct zebra_privs_t ripd_privs;
+
/* Master thread strucutre. */
extern struct thread_master *master;
#define IPV6_LEAVE_GROUP IPV6_DROP_MEMBERSHIP
#endif
-extern struct zebra_privs_t ripngd_privs;
-
/* Static utility function. */
static void ripng_enable_apply(struct interface *);
static void ripng_passive_interface_apply(struct interface *);
{
/* Allocate zebra structure. */
zclient = zclient_new(master);
- zclient_init(zclient, ZEBRA_ROUTE_RIPNG, 0);
+ zclient_init(zclient, ZEBRA_ROUTE_RIPNG, 0, &ripngd_privs);
zclient->zebra_connected = ripng_zebra_connected;
zclient->interface_up = ripng_interface_up;
ripng_changed_route,
};
-extern struct zebra_privs_t ripngd_privs;
-
/* Prototypes. */
void ripng_output_process(struct interface *, struct sockaddr_in6 *, int);
setsockopt_so_recvbuf(sock, 8096);
ret = setsockopt_ipv6_pktinfo(sock, 1);
if (ret < 0)
- return ret;
+ goto error;
#ifdef IPTOS_PREC_INTERNETCONTROL
ret = setsockopt_ipv6_tclass(sock, IPTOS_PREC_INTERNETCONTROL);
if (ret < 0)
- return ret;
+ goto error;
#endif
ret = setsockopt_ipv6_multicast_hops(sock, 255);
if (ret < 0)
- return ret;
+ goto error;
ret = setsockopt_ipv6_multicast_loop(sock, 0);
if (ret < 0)
- return ret;
+ goto error;
ret = setsockopt_ipv6_hoplimit(sock, 1);
if (ret < 0)
- return ret;
+ goto error;
memset(&ripaddr, 0, sizeof(ripaddr));
ripaddr.sin6_family = AF_INET6;
zlog_err("Can't bind ripng socket: %s.", safe_strerror(errno));
if (ripngd_privs.change(ZPRIVS_LOWER))
zlog_err("ripng_make_socket: could not lower privs");
- return ret;
+ goto error;
}
if (ripngd_privs.change(ZPRIVS_LOWER))
zlog_err("ripng_make_socket: could not lower privs");
return sock;
+
+error:
+ close(sock);
+ return ret;
}
/* Send RIPng packet. */
/* Extern variables. */
extern struct ripng *ripng;
-
+extern struct zebra_privs_t ripngd_privs;
extern struct thread_master *master;
/* Prototypes. */
return 0;
}
+struct zebra_privs_t isisd_privs;
+
static bool atexit_registered;
static void show_meminfo_at_exit(void)
return 0;
}
+struct zebra_privs_t isisd_privs;
+
static struct isis_vertex **vertices;
static size_t vertex_count;
execname = optarg;
break;
case 'c': /* --chuid <username>|<uid> */
- /* we copy the string just in case we need the
- * argument later. */
- changeuser = strdup(optarg);
- changeuser = strtok(changeuser, ":");
+ changeuser = strtok(optarg, ":");
changegroup = strtok(NULL, ":");
break;
case 'r': /* --chroot /new/root */
* appropriate */
if (strlen(vty_buf_trimmed) == 3
&& strncmp("end", vty_buf_trimmed, 3) == 0) {
+ cmd_free_strvec(vline);
continue;
}
} else if (rl_end && isspace((int)rl_line_buffer[rl_end - 1]))
vector_set(vline, NULL);
- describe = cmd_describe_command(vline, vty, &ret);
-
fprintf(stdout, "\n");
+ describe = cmd_describe_command(vline, vty, &ret);
+
/* Ambiguous and no match error. */
switch (ret) {
case CMD_ERR_AMBIGUOUS:
cmd_free_strvec(vline);
+ vector_free(describe);
fprintf(stdout, "%% Ambiguous command.\n");
rl_on_new_line();
return 0;
break;
case CMD_ERR_NO_MATCH:
cmd_free_strvec(vline);
+ vector_free(describe);
fprintf(stdout, "%% There is no matched command.\n");
rl_on_new_line();
return 0;
fp = open(history_file, O_CREAT | O_EXCL,
S_IRUSR | S_IWUSR);
- if (fp)
+ if (fp != -1)
close(fp);
read_history(history_file);
DEFUN (debug_zebra_pw,
debug_zebra_pw_cmd,
"[no] debug zebra pseudowires",
- "Negate a command or set its defaults\n"
+ NO_STR
DEBUG_STR
"Zebra configuration\n"
"Debug option set for zebra pseudowires\n")
NO_STR
"Interface Internet Protocol config commands\n"
"Set the IP address of an interface\n"
- "IP Address (e.g. 10.0.0.1/8)")
+ "IP Address (e.g. 10.0.0.1/8)\n")
{
int idx_ipv4_prefixlen = 3;
VTY_DECLVAR_CONTEXT(interface, ifp);
memset(&req, 0, sizeof req - NL_PKT_BUF_SIZE);
-
/*
* Count # nexthops so we can decide whether to use singlepath
* or multipath case.
}
}
- if (nexthop_num == 0 || !lsp->best_nhlfe) // unexpected
+ if ((nexthop_num == 0) || (!lsp->best_nhlfe && (cmd != RTM_DELROUTE)))
return 0;
- route_type = re_type_from_lsp_type(lsp->best_nhlfe->type);
-
req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
req.n.nlmsg_flags = NLM_F_CREATE | NLM_F_REQUEST;
req.n.nlmsg_type = cmd;
req.r.rtm_family = AF_MPLS;
req.r.rtm_table = RT_TABLE_MAIN;
req.r.rtm_dst_len = MPLS_LABEL_LEN_BITS;
- req.r.rtm_protocol = zebra2proto(route_type);
req.r.rtm_scope = RT_SCOPE_UNIVERSE;
req.r.rtm_type = RTN_UNICAST;
- if (cmd == RTM_NEWROUTE)
+ if (cmd == RTM_NEWROUTE) {
/* We do a replace to handle update. */
req.n.nlmsg_flags |= NLM_F_REPLACE;
+ /* set the protocol value if installing */
+ route_type = re_type_from_lsp_type(lsp->best_nhlfe->type);
+ req.r.rtm_protocol = zebra2proto(route_type);
+ }
+
/* Fill destination */
lse = mpls_lse_encode(lsp->ile.in_label, 0, 0, 1);
addattr_l(&req.n, sizeof req, RTA_DST, &lse, sizeof(mpls_lse_t));
sizeof(struct icmp6_filter));
if (ret < 0) {
zlog_info("ICMP6_FILTER set fail: %s", safe_strerror(errno));
+ close(sock);
return ret;
}
* if the operator has explicitly enabled RA. The enable request can also
* specify a RA interval (in seconds).
*/
-void zebra_interface_radv_set(struct zserv *client, int sock, u_short length,
+void zebra_interface_radv_set(struct zserv *client, u_short length,
struct zebra_vrf *zvrf, int enable)
{
struct stream *s;
extern void rtadv_init(struct zebra_ns *);
extern void rtadv_terminate(struct zebra_ns *);
extern void rtadv_cmd_init(void);
-extern void zebra_interface_radv_set(struct zserv *client, int sock,
+extern void zebra_interface_radv_set(struct zserv *client,
u_short length, struct zebra_vrf *zvrf,
int enable);
#include "zebra/rt.h"
#include "zebra/debug.h"
-int zebra_ipmr_route_stats(struct zserv *client, int fd, u_short length,
+int zebra_ipmr_route_stats(struct zserv *client, u_short length,
struct zebra_vrf *zvrf)
{
struct mcast_route_data mroute;
unsigned long long lastused;
};
-int zebra_ipmr_route_stats(struct zserv *client, int sock, u_short length,
+int zebra_ipmr_route_stats(struct zserv *client, u_short length,
struct zebra_vrf *zvf);
#endif
}
/* BFD peer/dst register/update */
-int zebra_ptm_bfd_dst_register(struct zserv *client, int sock, u_short length,
+int zebra_ptm_bfd_dst_register(struct zserv *client, u_short length,
int command, struct zebra_vrf *zvrf)
{
struct stream *s;
}
/* BFD peer/dst deregister */
-int zebra_ptm_bfd_dst_deregister(struct zserv *client, int sock, u_short length,
+int zebra_ptm_bfd_dst_deregister(struct zserv *client, u_short length,
struct zebra_vrf *zvrf)
{
struct stream *s;
}
/* BFD client register */
-int zebra_ptm_bfd_client_register(struct zserv *client, int sock,
+int zebra_ptm_bfd_client_register(struct zserv *client,
u_short length)
{
struct stream *s;
zlog_debug("bfd_client_register msg from client %s: length=%d",
zebra_route_string(client->proto), length);
+ s = client->ibuf;
+ pid = stream_getl(s);
+
if (ptm_cb.ptm_sock == -1) {
ptm_cb.t_timer = NULL;
thread_add_timer(zebrad.master, zebra_ptm_connect, NULL,
ptm_lib_append_msg(ptm_hdl, out_ctxt, ZEBRA_PTM_BFD_CLIENT_FIELD,
tmp_buf);
- s = client->ibuf;
-
- pid = stream_getl(s);
sprintf(tmp_buf, "%d", pid);
ptm_lib_append_msg(ptm_hdl, out_ctxt, ZEBRA_PTM_BFD_SEQID_FIELD,
tmp_buf);
void zebra_ptm_write(struct vty *vty);
int zebra_ptm_get_enable_state(void);
-int zebra_ptm_bfd_dst_register(struct zserv *client, int sock, u_short length,
+int zebra_ptm_bfd_dst_register(struct zserv *client, u_short length,
int command, struct zebra_vrf *zvrf);
-int zebra_ptm_bfd_dst_deregister(struct zserv *client, int sock, u_short length,
+int zebra_ptm_bfd_dst_deregister(struct zserv *client, u_short length,
struct zebra_vrf *zvrf);
void zebra_ptm_show_status(struct vty *vty, struct interface *ifp);
-int zebra_ptm_bfd_client_register(struct zserv *client, int sock,
+int zebra_ptm_bfd_client_register(struct zserv *client,
u_short length);
void zebra_ptm_if_init(struct zebra_if *zebra_ifp);
void zebra_ptm_if_set_ptm_state(struct interface *ifp,
"show mpls pseudowires",
SHOW_STR
MPLS_STR
- "Pseudowires")
+ "Pseudowires\n")
{
struct zebra_vrf *zvrf;
struct zebra_pw *pw;
/*
* Handle message from client to delete a remote MACIP for a VNI.
*/
-int zebra_vxlan_remote_macip_del(struct zserv *client, int sock, u_short length,
+int zebra_vxlan_remote_macip_del(struct zserv *client, u_short length,
struct zebra_vrf *zvrf)
{
struct stream *s;
* could be just the add of a MAC address or the add of a neighbor
* (IP+MAC).
*/
-int zebra_vxlan_remote_macip_add(struct zserv *client, int sock, u_short length,
+int zebra_vxlan_remote_macip_add(struct zserv *client, u_short length,
struct zebra_vrf *zvrf)
{
struct stream *s;
/*
* Handle message from client to delete a remote VTEP for a VNI.
*/
-int zebra_vxlan_remote_vtep_del(struct zserv *client, int sock, u_short length,
+int zebra_vxlan_remote_vtep_del(struct zserv *client, u_short length,
struct zebra_vrf *zvrf)
{
struct stream *s;
/*
* Handle message from client to add a remote VTEP for a VNI.
*/
-int zebra_vxlan_remote_vtep_add(struct zserv *client, int sock, u_short length,
+int zebra_vxlan_remote_vtep_add(struct zserv *client, u_short length,
struct zebra_vrf *zvrf)
{
struct stream *s;
* Handle message from client to enable/disable advertisement of g/w macip
* routes
*/
-int zebra_vxlan_advertise_gw_macip(struct zserv *client, int sock,
- u_short length, struct zebra_vrf *zvrf)
+int zebra_vxlan_advertise_gw_macip(struct zserv *client, u_short length,
+ struct zebra_vrf *zvrf)
{
struct stream *s;
int advertise;
* when disabled, the entries should be deleted and remote VTEPs and MACs
* uninstalled from the kernel.
*/
-int zebra_vxlan_advertise_all_vni(struct zserv *client, int sock,
+int zebra_vxlan_advertise_all_vni(struct zserv *client,
u_short length, struct zebra_vrf *zvrf)
{
struct stream *s;
extern int zebra_vxlan_local_neigh_del(struct interface *ifp,
struct interface *link_if,
struct ipaddr *ip);
-extern int zebra_vxlan_remote_macip_add(struct zserv *client, int sock,
+extern int zebra_vxlan_remote_macip_add(struct zserv *client,
u_short length, struct zebra_vrf *zvrf);
-extern int zebra_vxlan_remote_macip_del(struct zserv *client, int sock,
+extern int zebra_vxlan_remote_macip_del(struct zserv *client,
u_short length, struct zebra_vrf *zvrf);
extern int zebra_vxlan_local_mac_add_update(struct interface *ifp,
struct interface *br_if,
extern int zebra_vxlan_if_add(struct interface *ifp);
extern int zebra_vxlan_if_update(struct interface *ifp, u_int16_t chgflags);
extern int zebra_vxlan_if_del(struct interface *ifp);
-extern int zebra_vxlan_remote_vtep_add(struct zserv *client, int sock,
+extern int zebra_vxlan_remote_vtep_add(struct zserv *client,
u_short length, struct zebra_vrf *zvrf);
-extern int zebra_vxlan_remote_vtep_del(struct zserv *client, int sock,
+extern int zebra_vxlan_remote_vtep_del(struct zserv *client,
u_short length, struct zebra_vrf *zvrf);
-extern int zebra_vxlan_advertise_gw_macip(struct zserv *client, int sock,
+extern int zebra_vxlan_advertise_gw_macip(struct zserv *client,
u_short length,
struct zebra_vrf *zvrf);
-extern int zebra_vxlan_advertise_all_vni(struct zserv *client, int sock,
+extern int zebra_vxlan_advertise_all_vni(struct zserv *client,
u_short length,
struct zebra_vrf *zvrf);
extern void zebra_vxlan_init_tables(struct zebra_vrf *zvrf);
#include "nexthop.h"
#include "vrf.h"
#include "libfrr.h"
+#include "sockopt.h"
#include "zebra/zserv.h"
#include "zebra/zebra_ns.h"
}
/* Nexthop register */
-static int zserv_rnh_register(struct zserv *client, int sock, u_short length,
+static int zserv_rnh_register(struct zserv *client, u_short length,
rnh_type_t type, struct zebra_vrf *zvrf)
{
struct rnh *rnh;
}
/* Nexthop register */
-static int zserv_rnh_unregister(struct zserv *client, int sock, u_short length,
+static int zserv_rnh_unregister(struct zserv *client, u_short length,
rnh_type_t type, struct zebra_vrf *zvrf)
{
struct rnh *rnh;
#define ZEBRA_MIN_FEC_LENGTH 5
/* FEC register */
-static int zserv_fec_register(struct zserv *client, int sock, u_short length)
+static int zserv_fec_register(struct zserv *client, u_short length)
{
struct stream *s;
struct zebra_vrf *zvrf;
}
/* FEC unregister */
-static int zserv_fec_unregister(struct zserv *client, int sock, u_short length)
+static int zserv_fec_unregister(struct zserv *client, u_short length)
{
struct stream *s;
struct zebra_vrf *zvrf;
}
static void zread_mpls_labels(int command, struct zserv *client, u_short length,
- vrf_id_t vrf_id)
+ struct zebra_vrf *zvrf)
{
struct stream *s;
enum lsp_types_t type;
ifindex_t ifindex;
mpls_label_t in_label, out_label;
u_int8_t distance;
- struct zebra_vrf *zvrf;
-
- zvrf = vrf_info_lookup(vrf_id);
- if (!zvrf)
- return;
/* Get input stream. */
s = client->ibuf;
release_label_chunk(client->proto, client->instance, start, end);
}
static void zread_label_manager_request(int cmd, struct zserv *client,
- vrf_id_t vrf_id)
+ struct zebra_vrf *zvrf)
{
/* to avoid sending other messages like ZERBA_INTERFACE_UP */
if (cmd == ZEBRA_LABEL_MANAGER_CONNECT)
/* external label manager */
if (lm_is_external)
- zread_relay_label_manager_request(cmd, client, vrf_id);
+ zread_relay_label_manager_request(cmd, client,
+ zvrf_id(zvrf));
/* this is a label manager */
else {
if (cmd == ZEBRA_LABEL_MANAGER_CONNECT)
- zread_label_manager_connect(client, vrf_id);
+ zread_label_manager_connect(client,
+ zvrf_id(zvrf));
else {
/* Sanity: don't allow 'unidentified' requests */
if (!client->proto) {
return;
}
if (cmd == ZEBRA_GET_LABEL_CHUNK)
- zread_get_label_chunk(client, vrf_id);
+ zread_get_label_chunk(client,
+ zvrf_id(zvrf));
else if (cmd == ZEBRA_RELEASE_LABEL_CHUNK)
zread_release_label_chunk(client);
}
}
static int zread_pseudowire(int command, struct zserv *client, u_short length,
- vrf_id_t vrf_id)
+ struct zebra_vrf *zvrf)
{
struct stream *s;
- struct zebra_vrf *zvrf;
char ifname[IF_NAMESIZE];
ifindex_t ifindex;
int type;
uint8_t protocol;
struct zebra_pw *pw;
- zvrf = vrf_info_lookup(vrf_id);
- if (!zvrf)
- return -1;
-
/* Get input stream. */
s = client->ibuf;
zebra_vrf_update_all(client);
}
-static int zread_interface_set_master(struct zserv *client, int sock,
+static int zread_interface_set_master(struct zserv *client,
u_short length)
{
struct interface *master;
return 1;
}
-/* Handler of zebra service request. */
-static int zebra_client_read(struct thread *thread)
+static inline void zserv_handle_commands(struct zserv *client,
+ uint16_t command,
+ uint16_t length,
+ struct zebra_vrf *zvrf)
{
- int sock;
- struct zserv *client;
- size_t already;
- uint16_t length, command;
- uint8_t marker, version;
- vrf_id_t vrf_id;
- struct zebra_vrf *zvrf;
-
- /* Get thread data. Reset reading thread because I'm running. */
- sock = THREAD_FD(thread);
- client = THREAD_ARG(thread);
- client->t_read = NULL;
-
- if (client->t_suicide) {
- zebra_client_close(client);
- return -1;
- }
-
- /* Read length and command (if we don't have it already). */
- if ((already = stream_get_endp(client->ibuf)) < ZEBRA_HEADER_SIZE) {
- ssize_t nbyte;
- if (((nbyte = stream_read_try(client->ibuf, sock,
- ZEBRA_HEADER_SIZE - already))
- == 0)
- || (nbyte == -1)) {
- if (IS_ZEBRA_DEBUG_EVENT)
- zlog_debug("connection closed socket [%d]",
- sock);
- zebra_client_close(client);
- return -1;
- }
- if (nbyte != (ssize_t)(ZEBRA_HEADER_SIZE - already)) {
- /* Try again later. */
- zebra_event(ZEBRA_READ, sock, client);
- return 0;
- }
- already = ZEBRA_HEADER_SIZE;
- }
-
- /* Reset to read from the beginning of the incoming packet. */
- stream_set_getp(client->ibuf, 0);
-
- /* Fetch header values */
- length = stream_getw(client->ibuf);
- marker = stream_getc(client->ibuf);
- version = stream_getc(client->ibuf);
- vrf_id = stream_getw(client->ibuf);
- command = stream_getw(client->ibuf);
-
- if (marker != ZEBRA_HEADER_MARKER || version != ZSERV_VERSION) {
- zlog_err(
- "%s: socket %d version mismatch, marker %d, version %d",
- __func__, sock, marker, version);
- zebra_client_close(client);
- return -1;
- }
- if (length < ZEBRA_HEADER_SIZE) {
- zlog_warn(
- "%s: socket %d message length %u is less than header size %d",
- __func__, sock, length, ZEBRA_HEADER_SIZE);
- zebra_client_close(client);
- return -1;
- }
- if (length > STREAM_SIZE(client->ibuf)) {
- zlog_warn(
- "%s: socket %d message length %u exceeds buffer size %lu",
- __func__, sock, length,
- (u_long)STREAM_SIZE(client->ibuf));
- zebra_client_close(client);
- return -1;
- }
-
- /* Read rest of data. */
- if (already < length) {
- ssize_t nbyte;
- if (((nbyte = stream_read_try(client->ibuf, sock,
- length - already))
- == 0)
- || (nbyte == -1)) {
- if (IS_ZEBRA_DEBUG_EVENT)
- zlog_debug(
- "connection closed [%d] when reading zebra data",
- sock);
- zebra_client_close(client);
- return -1;
- }
- if (nbyte != (ssize_t)(length - already)) {
- /* Try again later. */
- zebra_event(ZEBRA_READ, sock, client);
- return 0;
- }
- }
-
- length -= ZEBRA_HEADER_SIZE;
-
- /* Debug packet information. */
- if (IS_ZEBRA_DEBUG_EVENT)
- zlog_debug("zebra message comes from socket [%d]", sock);
-
- if (IS_ZEBRA_DEBUG_PACKET && IS_ZEBRA_DEBUG_RECV)
- zlog_debug("zebra message received [%s] %d in VRF %u",
- zserv_command_string(command), length, vrf_id);
-
- client->last_read_time = monotime(NULL);
- client->last_read_cmd = command;
-
- zvrf = zebra_vrf_lookup_by_id(vrf_id);
- if (!zvrf) {
- if (IS_ZEBRA_DEBUG_PACKET && IS_ZEBRA_DEBUG_RECV)
- zlog_debug("zebra received unknown VRF[%u]", vrf_id);
- goto zclient_read_out;
- }
-
switch (command) {
case ZEBRA_ROUTER_ID_ADD:
zread_router_id_add(client, length, zvrf);
zread_hello(client);
break;
case ZEBRA_NEXTHOP_REGISTER:
- zserv_rnh_register(client, sock, length, RNH_NEXTHOP_TYPE,
+ zserv_rnh_register(client, length, RNH_NEXTHOP_TYPE,
zvrf);
break;
case ZEBRA_NEXTHOP_UNREGISTER:
- zserv_rnh_unregister(client, sock, length, RNH_NEXTHOP_TYPE,
+ zserv_rnh_unregister(client, length, RNH_NEXTHOP_TYPE,
zvrf);
break;
case ZEBRA_IMPORT_ROUTE_REGISTER:
- zserv_rnh_register(client, sock, length, RNH_IMPORT_CHECK_TYPE,
+ zserv_rnh_register(client, length, RNH_IMPORT_CHECK_TYPE,
zvrf);
break;
case ZEBRA_IMPORT_ROUTE_UNREGISTER:
- zserv_rnh_unregister(client, sock, length,
+ zserv_rnh_unregister(client, length,
RNH_IMPORT_CHECK_TYPE, zvrf);
break;
case ZEBRA_BFD_DEST_UPDATE:
case ZEBRA_BFD_DEST_REGISTER:
- zebra_ptm_bfd_dst_register(client, sock, length, command, zvrf);
+ zebra_ptm_bfd_dst_register(client, length, command, zvrf);
break;
case ZEBRA_BFD_DEST_DEREGISTER:
- zebra_ptm_bfd_dst_deregister(client, sock, length, zvrf);
+ zebra_ptm_bfd_dst_deregister(client, length, zvrf);
break;
case ZEBRA_VRF_UNREGISTER:
zread_vrf_unregister(client, length, zvrf);
break;
case ZEBRA_BFD_CLIENT_REGISTER:
- zebra_ptm_bfd_client_register(client, sock, length);
+ zebra_ptm_bfd_client_register(client, length);
break;
case ZEBRA_INTERFACE_ENABLE_RADV:
#if defined(HAVE_RTADV)
- zebra_interface_radv_set(client, sock, length, zvrf, 1);
+ zebra_interface_radv_set(client, length, zvrf, 1);
#endif
break;
case ZEBRA_INTERFACE_DISABLE_RADV:
#if defined(HAVE_RTADV)
- zebra_interface_radv_set(client, sock, length, zvrf, 0);
+ zebra_interface_radv_set(client, length, zvrf, 0);
#endif
break;
case ZEBRA_MPLS_LABELS_ADD:
case ZEBRA_MPLS_LABELS_DELETE:
- zread_mpls_labels(command, client, length, vrf_id);
+ zread_mpls_labels(command, client, length, zvrf);
break;
case ZEBRA_IPMR_ROUTE_STATS:
- zebra_ipmr_route_stats(client, sock, length, zvrf);
+ zebra_ipmr_route_stats(client, length, zvrf);
break;
case ZEBRA_LABEL_MANAGER_CONNECT:
case ZEBRA_GET_LABEL_CHUNK:
case ZEBRA_RELEASE_LABEL_CHUNK:
- zread_label_manager_request(command, client, vrf_id);
+ zread_label_manager_request(command, client, zvrf);
break;
case ZEBRA_FEC_REGISTER:
- zserv_fec_register(client, sock, length);
+ zserv_fec_register(client, length);
break;
case ZEBRA_FEC_UNREGISTER:
- zserv_fec_unregister(client, sock, length);
+ zserv_fec_unregister(client, length);
break;
case ZEBRA_ADVERTISE_DEFAULT_GW:
- zebra_vxlan_advertise_gw_macip(client, sock, length, zvrf);
+ zebra_vxlan_advertise_gw_macip(client, length, zvrf);
break;
case ZEBRA_ADVERTISE_ALL_VNI:
- zebra_vxlan_advertise_all_vni(client, sock, length, zvrf);
+ zebra_vxlan_advertise_all_vni(client, length, zvrf);
break;
case ZEBRA_REMOTE_VTEP_ADD:
- zebra_vxlan_remote_vtep_add(client, sock, length, zvrf);
+ zebra_vxlan_remote_vtep_add(client, length, zvrf);
break;
case ZEBRA_REMOTE_VTEP_DEL:
- zebra_vxlan_remote_vtep_del(client, sock, length, zvrf);
+ zebra_vxlan_remote_vtep_del(client, length, zvrf);
break;
case ZEBRA_REMOTE_MACIP_ADD:
- zebra_vxlan_remote_macip_add(client, sock, length, zvrf);
+ zebra_vxlan_remote_macip_add(client, length, zvrf);
break;
case ZEBRA_REMOTE_MACIP_DEL:
- zebra_vxlan_remote_macip_del(client, sock, length, zvrf);
+ zebra_vxlan_remote_macip_del(client, length, zvrf);
break;
case ZEBRA_INTERFACE_SET_MASTER:
- zread_interface_set_master(client, sock, length);
+ zread_interface_set_master(client, length);
break;
case ZEBRA_PW_ADD:
case ZEBRA_PW_DELETE:
case ZEBRA_PW_SET:
case ZEBRA_PW_UNSET:
- zread_pseudowire(command, client, length, vrf_id);
+ zread_pseudowire(command, client, length, zvrf);
break;
default:
zlog_info("Zebra received unknown command %d", command);
break;
}
+}
+
+/* Handler of zebra service request. */
+static int zebra_client_read(struct thread *thread)
+{
+ int sock;
+ struct zserv *client;
+ size_t already;
+ uint16_t length, command;
+ uint8_t marker, version;
+ vrf_id_t vrf_id;
+ struct zebra_vrf *zvrf;
+ int packets = 10;
+
+ /* Get thread data. Reset reading thread because I'm running. */
+ sock = THREAD_FD(thread);
+ client = THREAD_ARG(thread);
+ client->t_read = NULL;
if (client->t_suicide) {
- /* No need to wait for thread callback, just kill immediately.
- */
zebra_client_close(client);
return -1;
}
+ while (packets) {
+ /* Read length and command (if we don't have it already). */
+ if ((already = stream_get_endp(client->ibuf))
+ < ZEBRA_HEADER_SIZE) {
+ ssize_t nbyte;
+ if (((nbyte =
+ stream_read_try(client->ibuf, sock,
+ ZEBRA_HEADER_SIZE - already))
+ == 0)
+ || (nbyte == -1)) {
+ if (IS_ZEBRA_DEBUG_EVENT)
+ zlog_debug("connection closed socket [%d]",
+ sock);
+ zebra_client_close(client);
+ return -1;
+ }
+ if (nbyte != (ssize_t)(ZEBRA_HEADER_SIZE - already)) {
+ /* Try again later. */
+ zebra_event(ZEBRA_READ, sock, client);
+ return 0;
+ }
+ already = ZEBRA_HEADER_SIZE;
+ }
+
+ /* Reset to read from the beginning of the incoming packet. */
+ stream_set_getp(client->ibuf, 0);
+
+ /* Fetch header values */
+ length = stream_getw(client->ibuf);
+ marker = stream_getc(client->ibuf);
+ version = stream_getc(client->ibuf);
+ vrf_id = stream_getw(client->ibuf);
+ command = stream_getw(client->ibuf);
+
+ if (marker != ZEBRA_HEADER_MARKER || version != ZSERV_VERSION) {
+ zlog_err(
+ "%s: socket %d version mismatch, marker %d, version %d",
+ __func__, sock, marker, version);
+ zebra_client_close(client);
+ return -1;
+ }
+ if (length < ZEBRA_HEADER_SIZE) {
+ zlog_warn(
+ "%s: socket %d message length %u is less than header size %d",
+ __func__, sock, length, ZEBRA_HEADER_SIZE);
+ zebra_client_close(client);
+ return -1;
+ }
+ if (length > STREAM_SIZE(client->ibuf)) {
+ zlog_warn(
+ "%s: socket %d message length %u exceeds buffer size %lu",
+ __func__, sock, length,
+ (u_long)STREAM_SIZE(client->ibuf));
+ zebra_client_close(client);
+ return -1;
+ }
+
+ /* Read rest of data. */
+ if (already < length) {
+ ssize_t nbyte;
+ if (((nbyte = stream_read_try(client->ibuf, sock,
+ length - already))
+ == 0)
+ || (nbyte == -1)) {
+ if (IS_ZEBRA_DEBUG_EVENT)
+ zlog_debug(
+ "connection closed [%d] when reading zebra data",
+ sock);
+ zebra_client_close(client);
+ return -1;
+ }
+ if (nbyte != (ssize_t)(length - already)) {
+ /* Try again later. */
+ zebra_event(ZEBRA_READ, sock, client);
+ return 0;
+ }
+ }
+
+ length -= ZEBRA_HEADER_SIZE;
+
+ /* Debug packet information. */
+ if (IS_ZEBRA_DEBUG_EVENT)
+ zlog_debug("zebra message comes from socket [%d]", sock);
+
+ if (IS_ZEBRA_DEBUG_PACKET && IS_ZEBRA_DEBUG_RECV)
+ zlog_debug("zebra message received [%s] %d in VRF %u",
+ zserv_command_string(command), length, vrf_id);
+
+ client->last_read_time = monotime(NULL);
+ client->last_read_cmd = command;
+
+ zvrf = zebra_vrf_lookup_by_id(vrf_id);
+ if (!zvrf) {
+ if (IS_ZEBRA_DEBUG_PACKET && IS_ZEBRA_DEBUG_RECV)
+ zlog_debug("zebra received unknown VRF[%u]", vrf_id);
+ goto zclient_read_out;
+ }
+
+ zserv_handle_commands(client, command, length, zvrf);
+
+ if (client->t_suicide) {
+ /* No need to wait for thread callback, just kill immediately.
+ */
+ zebra_client_close(client);
+ return -1;
+ }
+ packets -= 1;
+ stream_reset(client->ibuf);
+ }
+
zclient_read_out:
stream_reset(client->ibuf);
zebra_event(ZEBRA_READ, sock, client);
unlink(suna->sun_path);
}
+ zserv_privs.change(ZPRIVS_RAISE);
+ setsockopt_so_recvbuf(sock, 1048576);
+ setsockopt_so_sendbuf(sock, 1048576);
+ zserv_privs.change(ZPRIVS_LOWER);
+
if (sa.ss_family != AF_UNIX && zserv_privs.change(ZPRIVS_RAISE))
zlog_err("Can't raise privileges");
ip_forwarding_cmd,
"ip forwarding",
IP_STR
- "Turn on IP forwarding")
+ "Turn on IP forwarding\n")
{
int ret;
"no ip forwarding",
NO_STR
IP_STR
- "Turn off IP forwarding")
+ "Turn off IP forwarding\n")
{
int ret;
ipv6_forwarding_cmd,
"ipv6 forwarding",
IPV6_STR
- "Turn on IPv6 forwarding")
+ "Turn on IPv6 forwarding\n")
{
int ret;
"no ipv6 forwarding",
NO_STR
IPV6_STR
- "Turn off IPv6 forwarding")
+ "Turn off IPv6 forwarding\n")
{
int ret;