| _Security_ | security@lists.frrouting.org |
| _Technical Steering Committee_ | tsc@lists.frrouting.org |
+The Development list is used to discuss and document general issues
+related to project development and governance. The public Slack
+instance, frrouting.slack.com, and weekly technical meetings provide a
+higher bandwidth channel for discussions. The results of such
+discussions must be reflected in updates, as appropriate, to code (i.e.,
+merges), [github](https://github.com/FRRouting/frr/issues) tracked
+issues, and for governance or process changes, updates to the
+Development list and either this file or information posted at
+[https://frrouting.org/](https://frrouting.org/).
+
### Changelog
int ifindex = if_nametoindex(ifp->name);
if(ifindex > 0) {
unsigned char eui[8];
- rc = if_eui64(ifp->name, ifindex, eui);
+ rc = if_eui64(ifindex, eui);
if(rc < 0)
continue;
memcpy(myid, eui, 8);
ifname = if_indextoname(i, buf);
if(ifname == NULL)
continue;
- rc = if_eui64(ifname, i, eui);
+ rc = if_eui64(i, eui);
if(rc < 0)
continue;
memcpy(myid, eui, 8);
}
int
-if_eui64(char *ifname, int ifindex, unsigned char *eui)
+if_eui64(int ifindex, unsigned char *eui)
{
struct interface *ifp = if_lookup_by_index(ifindex, VRF_DEFAULT);
if (ifp == NULL) {
const unsigned char *gate, int ifindex, unsigned int metric,
const unsigned char *newgate, int newifindex,
unsigned int newmetric);
-int if_eui64(char *ifname, int ifindex, unsigned char *eui);
+int if_eui64(int ifindex, unsigned char *eui);
int gettime(struct timeval *tv);
int read_random_bytes(void *buf, size_t len);
static void display_vni(struct vty *vty, struct bgpevpn *vpn, json_object *json)
{
- char buf1[INET6_ADDRSTRLEN];
+ char buf1[RD_ADDRSTRLEN];
char *ecom_str;
struct listnode *node, *nnode;
struct ecommunity *ecom;
is_vni_live(vpn) ? "Yes" : "No");
json_object_string_add(
json, "rd",
- prefix_rd2str(&vpn->prd, buf1, RD_ADDRSTRLEN));
+ prefix_rd2str(&vpn->prd, buf1, sizeof(buf1)));
json_object_string_add(json, "originatorIp",
inet_ntoa(vpn->originator_ip));
json_object_string_add(json, "advertiseGatewayMacip",
vty_out(vty, "\n");
vty_out(vty, " RD: %s\n",
- prefix_rd2str(&vpn->prd, buf1, RD_ADDRSTRLEN));
+ prefix_rd2str(&vpn->prd, buf1, sizeof(buf1)));
vty_out(vty, " Originator IP: %s\n",
inet_ntoa(vpn->originator_ip));
vty_out(vty, " Advertise-gw-macip : %s\n",
json_object *json_export_rtl;
struct bgpevpn *vpn = (struct bgpevpn *)backet->data;
char buf1[10];
- char buf2[INET6_ADDRSTRLEN];
+ char buf2[RD_ADDRSTRLEN];
char rt_buf[25];
char *ecom_str;
struct listnode *node, *nnode;
inet_ntoa(vpn->originator_ip));
json_object_string_add(
json_vni, "rd",
- prefix_rd2str(&vpn->prd, buf2, RD_ADDRSTRLEN));
+ prefix_rd2str(&vpn->prd, buf2, sizeof(buf2)));
} else {
vty_out(vty, "%-1s %-10u %-15s %-21s", buf1, vpn->vni,
inet_ntoa(vpn->originator_ip),
- prefix_rd2str(&vpn->prd, buf2, RD_ADDRSTRLEN));
+ prefix_rd2str(&vpn->prd, buf2, sizeof(buf2)));
}
for (ALL_LIST_ELEMENTS(vpn->import_rtl, node, nnode, ecom)) {
static void write_vni_config(struct vty *vty, struct bgpevpn *vpn)
{
- char buf1[INET6_ADDRSTRLEN];
+ char buf1[RD_ADDRSTRLEN];
char *ecom_str;
struct listnode *node, *nnode;
struct ecommunity *ecom;
vty_out(vty, " vni %d\n", vpn->vni);
if (is_rd_configured(vpn))
vty_out(vty, " rd %s\n",
- prefix_rd2str(&vpn->prd, buf1, RD_ADDRSTRLEN));
+ prefix_rd2str(&vpn->prd, buf1, sizeof(buf1)));
if (is_import_rt_configured(vpn)) {
for (ALL_LIST_ELEMENTS(vpn->import_rtl, node, nnode,
struct rd_as rd_as;
struct rd_ip rd_ip;
- if (size < RD_ADDRSTRLEN)
- return NULL;
+ assert(size >= RD_ADDRSTRLEN);
pnt = prd->val;
return buf;
}
#endif
- return NULL;
+
+ snprintf(buf, size, "Unknown Type: %d", type);
+ return buf;
}
vty_out(vty, " Imported from %s:%s\n",
prefix_rd2str(
(struct prefix_rd *)&prn->p,
- buf1, RD_ADDRSTRLEN),
+ buf1, sizeof(buf1)),
buf2);
}
}
json_peer, "routerId",
inet_ntop(AF_INET,
&binfo->peer->remote_id, buf1,
- BUFSIZ));
+ sizeof(buf1)));
if (binfo->peer->hostname)
json_object_string_add(
inet_ntop(
AF_INET,
&binfo->peer->remote_id,
- buf1, BUFSIZ));
+ buf1, sizeof(buf1)));
}
}
continue;
if (rn->info != NULL) {
struct prefix_rd prd;
- char rd[BUFSIZ];
+ char rd[RD_ADDRSTRLEN];
memcpy(&prd, &(rn->p), sizeof(struct prefix_rd));
- if (prefix_rd2str(&prd, rd, BUFSIZ) == NULL)
- sprintf(rd,
- "Unknown Type: %u",
- decode_rd_type(prd.val));
+ prefix_rd2str(&prd, rd, sizeof(rd));
bgp_show_table(vty, bgp, safi, rn->info, type,
output_arg, use_json,
rd, next == NULL,
struct prefix *p;
struct peer *peer;
struct listnode *node, *nnode;
- char buf1[INET6_ADDRSTRLEN];
+ char buf1[RD_ADDRSTRLEN];
char buf2[INET6_ADDRSTRLEN];
#if defined(HAVE_CUMULUS)
char buf3[EVPN_ROUTE_STRLEN];
#if defined(HAVE_CUMULUS)
if (safi == SAFI_EVPN)
vty_out(vty, "BGP routing table entry for %s%s%s\n",
- prd ? prefix_rd2str(prd, buf1, RD_ADDRSTRLEN)
+ prd ? prefix_rd2str(prd, buf1, sizeof(buf1))
: "",
prd ? ":" : "",
bgp_evpn_route2str((struct prefix_evpn *)p,
vty_out(vty, "BGP routing table entry for %s%s%s/%d\n",
((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)
? prefix_rd2str(prd, buf1,
- RD_ADDRSTRLEN)
+ sizeof(buf1))
: ""),
safi == SAFI_MPLS_VPN ? ":" : "",
inet_ntop(p->family, &p->u.prefix, buf2,
vty_out(vty, "BGP routing table entry for %s%s%s/%d\n",
((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
|| safi == SAFI_EVPN)
- ? prefix_rd2str(prd, buf1, RD_ADDRSTRLEN)
- : ""),
+ ? prefix_rd2str(prd, buf1, sizeof(buf1))
+ : ""),
((safi == SAFI_MPLS_VPN) || (safi == SAFI_EVPN)) ? ":"
: "",
buf2, p->prefixlen);
afi_t afi = AFI_MAX;
int idx = 0;
- (void)argv_find_and_parse_afi(argv, argc, &idx, &afi);
+ if (!argv_find_and_parse_afi(argv, argc, &idx, &afi)) {
+ vty_out(vty, "%% Malformed Address Family\n");
+ return CMD_WARNING;
+ }
+
ret = str2prefix_rd(argv[5]->arg, &prd);
if (!ret) {
vty_out(vty, "%% Malformed Route Distinguisher\n");
return CMD_WARNING;
}
+
return bgp_show_route(vty, NULL, argv[6]->arg, afi, SAFI_MPLS_VPN, &prd,
0, BGP_PATH_ALL, use_json(argc, argv));
}
prd = (struct prefix_rd *)&prn->p;
/* "network" configuration display. */
- prefix_rd2str(prd, rdbuf, RD_ADDRSTRLEN);
+ prefix_rd2str(prd, rdbuf, sizeof(rdbuf));
label = decode_label(&bgp_static->label);
vty_out(vty, " network %s/%d rd %s",
prd = (struct prefix_rd *)&prn->p;
/* "network" configuration display. */
- prefix_rd2str(prd, rdbuf, RD_ADDRSTRLEN);
+ prefix_rd2str(prd, rdbuf, sizeof(rdbuf));
if (p->u.prefix_evpn.route_type == 5) {
char local_buf[PREFIX_STRLEN];
uint8_t family = IS_EVPN_PREFIX_IPADDR_V4((struct prefix_evpn *)p)
aggregator =
XCALLOC(MTYPE_ROUTE_MAP_COMPILED, sizeof(struct aggregator));
- sscanf(arg, "%s %s", as, address);
+ if (sscanf(arg, "%s %s", as, address) != 2) {
+ XFREE(MTYPE_ROUTE_MAP_COMPILED, aggregator);
+ return NULL;
+ }
aggregator->as = strtoul(as, NULL, 10);
ret = inet_aton(address, &aggregator->address);
void bgp_config_write_coalesce_time(struct vty *vty, struct bgp *bgp)
{
- if (bgp->coalesce_time != BGP_DEFAULT_SUBGROUP_COALESCE_TIME)
+ if (!bgp->heuristic_coalesce)
vty_out(vty, " coalesce-time %u\n", bgp->coalesce_time);
}
int idx = 0;
argv_find(argv, argc, "(0-4294967295)", &idx);
+ bgp->heuristic_coalesce = false;
bgp->coalesce_time = strtoul(argv[idx]->arg, NULL, 10);
return CMD_SUCCESS;
}
{
VTY_DECLVAR_CONTEXT(bgp, bgp);
+ bgp->heuristic_coalesce = true;
bgp->coalesce_time = BGP_DEFAULT_SUBGROUP_COALESCE_TIME;
return CMD_SUCCESS;
}
}
/* Check peer's AS number and determines if this peer is IBGP or EBGP */
-static bgp_peer_sort_t peer_calc_sort(struct peer *peer)
+static inline bgp_peer_sort_t peer_calc_sort(struct peer *peer)
{
struct bgp *bgp;
peer_dst->local_as = peer_src->local_as;
peer_dst->ifindex = peer_src->ifindex;
peer_dst->port = peer_src->port;
- peer_sort(peer_dst);
+ (void)peer_sort(peer_dst);
peer_dst->rmap_type = peer_src->rmap_type;
/* Timers */
hash_get(bgp->peerhash, peer, hash_alloc_intern);
/* Adjust update-group coalesce timer heuristics for # peers. */
- long ct = BGP_DEFAULT_SUBGROUP_COALESCE_TIME
- + (bgp->peer->count * BGP_PEER_ADJUST_SUBGROUP_COALESCE_TIME);
- bgp->coalesce_time = MIN(BGP_MAX_SUBGROUP_COALESCE_TIME, ct);
+ if (bgp->heuristic_coalesce) {
+ long ct = BGP_DEFAULT_SUBGROUP_COALESCE_TIME
+ + (bgp->peer->count
+ * BGP_PEER_ADJUST_SUBGROUP_COALESCE_TIME);
+ bgp->coalesce_time = MIN(BGP_MAX_SUBGROUP_COALESCE_TIME, ct);
+ }
active = peer_active(peer);
_Atomic uint32_t wpkt_quanta; // max # packets to write per i/o cycle
_Atomic uint32_t rpkt_quanta; // max # packets to read per i/o cycle
- u_int32_t coalesce_time;
+ /* Automatic coalesce adjust on/off */
+ bool heuristic_coalesce;
+ /* Actual coalesce time */
+ uint32_t coalesce_time;
u_int32_t addpath_tx_id;
int addpath_tx_used[AFI_MAX][SAFI_MAX];
#if BGP_VNC_DEBUG_MATCH_GROUP
{
- char buf[BUFSIZ];
+ char buf[PREFIX_STRLEN];
- prefix2str(vn, buf, BUFSIZ);
+ prefix2str(vn, buf, sizeof(buf));
vnc_zlog_debug_verbose("%s: vn prefix: %s", __func__, buf);
- prefix2str(un, buf, BUFSIZ);
+ prefix2str(un, buf, sizeof(buf));
vnc_zlog_debug_verbose("%s: un prefix: %s", __func__, buf);
vnc_zlog_debug_verbose(
return CMD_WARNING_CONFIG_FAILED;
}
- argv_find_and_parse_afi(argv, argc, &idx, &afi);
+ if (!argv_find_and_parse_afi(argv, argc, &idx, &afi)) {
+ vty_out(vty, "%% Malformed Address Family\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+
if (argv[idx-1]->text[0] == 'z')
is_bgp = 0;
idx += 2; /* skip afi and keyword */
return CMD_WARNING_CONFIG_FAILED;
}
- argv_find_and_parse_afi(argv, argc, &idx, &afi);
+ if (!argv_find_and_parse_afi(argv, argc, &idx, &afi)) {
+ vty_out(vty, "%% Malformed Address Family\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+
if (argv[idx-1]->text[0] == 'z')
is_bgp = 0;
idx = argc - 1;
}
if (rfg->rd.prefixlen) {
- char buf[BUFSIZ];
- buf[0] = buf[BUFSIZ - 1] = 0;
+ char buf[RD_ADDRSTRLEN];
if (AF_UNIX == rfg->rd.family) {
vty_out(vty, " rd auto:nh:%d\n",
value);
- } else {
-
- if (!prefix_rd2str(&rfg->rd, buf,
- BUFSIZ)
- || !buf[0] || buf[BUFSIZ - 1]) {
-
- vty_out(vty,
- "!Error: Can't convert rd\n");
- } else {
- vty_out(vty, " rd %s\n", buf);
- }
- }
+ } else
+ vty_out(vty, " rd %s\n",
+ prefix_rd2str(&rfg->rd, buf,
+ sizeof(buf)));
}
if (rfg->rt_import_list && rfg->rt_export_list
vty_out(vty, " vnc defaults\n");
if (hc->default_rd.prefixlen) {
- char buf[BUFSIZ];
- buf[0] = buf[BUFSIZ - 1] = 0;
+ char buf[RD_ADDRSTRLEN];
if (AF_UNIX == hc->default_rd.family) {
uint16_t value = 0;
vty_out(vty, " rd auto:vn:%d\n",
value);
- } else {
-
- if (!prefix_rd2str(&hc->default_rd, buf,
- BUFSIZ)
- || !buf[0] || buf[BUFSIZ - 1]) {
-
- vty_out(vty,
- "!Error: Can't convert rd\n");
- } else {
- vty_out(vty, " rd %s\n", buf);
- }
- }
+ } else
+ vty_out(vty, " rd %s\n",
+ prefix_rd2str(&hc->default_rd,
+ buf,
+ sizeof(buf)));
}
if (hc->default_response_lifetime) {
vty_out(vty, " response-lifetime ");
vty_out(vty, " vnc nve-group %s\n", rfg->name);
if (rfg->vn_prefix.family && rfg->vn_node) {
- char buf[BUFSIZ];
- buf[0] = buf[BUFSIZ - 1] = 0;
+ char buf[PREFIX_STRLEN];
prefix2str(&rfg->vn_prefix, buf,
- BUFSIZ);
- if (!buf[0] || buf[BUFSIZ - 1]) {
- vty_out(vty,
- "!Error: Can't convert prefix\n");
- } else {
- vty_out(vty, " prefix %s %s\n",
- "vn", buf);
- }
+ sizeof(buf));
+ vty_out(vty, " prefix %s %s\n",
+ "vn", buf);
}
if (rfg->un_prefix.family && rfg->un_node) {
- char buf[BUFSIZ];
- buf[0] = buf[BUFSIZ - 1] = 0;
+ char buf[PREFIX_STRLEN];
+
prefix2str(&rfg->un_prefix, buf,
- BUFSIZ);
- if (!buf[0] || buf[BUFSIZ - 1]) {
- vty_out(vty,
- "!Error: Can't convert prefix\n");
- } else {
- vty_out(vty, " prefix %s %s\n",
- "un", buf);
- }
+ sizeof(buf));
+ vty_out(vty, " prefix %s %s\n",
+ "un", buf);
}
if (rfg->rd.prefixlen) {
- char buf[BUFSIZ];
- buf[0] = buf[BUFSIZ - 1] = 0;
+ char buf[RD_ADDRSTRLEN];
if (AF_UNIX == rfg->rd.family) {
" rd auto:vn:%d\n",
value);
- } else {
-
- if (!prefix_rd2str(&rfg->rd,
- buf, BUFSIZ)
- || !buf[0]
- || buf[BUFSIZ - 1]) {
-
- vty_out(vty,
- "!Error: Can't convert rd\n");
- } else {
- vty_out(vty,
- " rd %s\n",
- buf);
- }
- }
+ } else
+ vty_out(vty,
+ " rd %s\n",
+ prefix_rd2str(&rfg->rd,
+ buf,
+ sizeof(buf)));
}
if (rfg->flags & RFAPI_RFG_RESPONSE_LIFETIME) {
vty_out(vty, " response-lifetime ");
afi_t afi; /* of the VN address */
struct bgp_node *bn;
struct bgp_info *bi;
- char buf[BUFSIZ];
- char buf2[BUFSIZ];
+ char buf[PREFIX_STRLEN];
+ char buf2[RD_ADDRSTRLEN];
struct prefix_rd prd0;
- prefix2str(p, buf, BUFSIZ);
- buf[BUFSIZ - 1] = 0; /* guarantee NUL-terminated */
-
- prefix_rd2str(prd, buf2, BUFSIZ);
- buf2[BUFSIZ - 1] = 0;
+ prefix2str(p, buf, sizeof(buf));
afi = family2afi(p->family);
assert(afi == AFI_IP || afi == AFI_IP6);
vnc_zlog_debug_verbose(
"%s: peer=%p, prefix=%s, prd=%s afi=%d, safi=%d bn=%p, bn->info=%p",
- __func__, peer, buf, buf2, afi, safi, bn,
+ __func__, peer, buf,
+ prefix_rd2str(prd, buf2, sizeof(buf2)), afi, safi, bn,
(bn ? bn->info : NULL));
for (bi = (bn ? bn->info : NULL); bi; bi = bi->next) {
rfapiProcessWithdraw(peer, rfd, p, prd, NULL, afi, safi, type, kill);
if (bi) {
- char buf[BUFSIZ];
-
- prefix2str(p, buf, BUFSIZ);
- buf[BUFSIZ - 1] = 0; /* guarantee NUL-terminated */
+ char buf[PREFIX_STRLEN];
+ prefix2str(p, buf, sizeof(buf));
vnc_zlog_debug_verbose(
"%s: Found route (safi=%d) to delete at prefix %s",
__func__, safi, buf);
uint32_t label_val;
struct bgp_attr_encap_subtlv *encaptlv;
- char buf[BUFSIZ];
- char buf2[BUFSIZ];
+ char buf[PREFIX_STRLEN];
+ char buf2[RD_ADDRSTRLEN];
#if 0 /* unused? */
struct prefix pfx_buf;
#endif
else
label_val = MPLS_LABEL_IMPLICIT_NULL;
- prefix_rd2str(prd, buf2, BUFSIZ);
- buf2[BUFSIZ - 1] = 0;
-
+ prefix_rd2str(prd, buf2, sizeof(buf2));
afi = family2afi(p->family);
assert(afi == AFI_IP || afi == AFI_IP6);
}
- prefix2str(p, buf, BUFSIZ);
- buf[BUFSIZ - 1] = 0; /* guarantee NUL-terminated */
+ prefix2str(p, buf, sizeof(buf));
/*
* At this point:
}
{
- char buf[BUFSIZ];
+ char buf[PREFIX_STRLEN];
char *s;
- prefix2str(&p, buf, BUFSIZ);
- buf[BUFSIZ - 1] = 0; /* guarantee NUL-terminated */
+ prefix2str(&p, buf, sizeof(buf));
vnc_zlog_debug_verbose("%s(rfd=%p, target=%s, ppNextHop=%p)",
__func__, rfd, buf, ppNextHopEntry);
{
- char buf[BUFSIZ];
+ char buf[PREFIX_STRLEN];
- prefix2str(&p, buf, BUFSIZ);
- buf[BUFSIZ - 1] = 0; /* guarantee NUL-terminated */
+ prefix2str(&p, buf, sizeof(buf));
vnc_zlog_debug_verbose(
"%s(rfd=%p, pfx=%s, lifetime=%d, opts_un=%p, opts_vn=%p, action=%s)",
__func__, rfd, buf, lifetime, options_un, options_vn,
4); /* low order 4 bytes */
}
{
- char buf[BUFSIZ];
- buf[0] = 0;
- prefix_rd2str(rd, buf, BUFSIZ);
- buf[BUFSIZ - 1] = 0;
+ char buf[RD_ADDRSTRLEN];
+
vnc_zlog_debug_verbose("%s: auto-RD is set to %s", __func__,
- buf);
+ prefix_rd2str(rd, buf, sizeof(buf)));
}
return 0;
}
#include "bgpd/bgp_route.h"
#include "bgpd/bgp_mplsvpn.h" /* prefix_rd2str() */
#include "bgpd/bgp_vnc_types.h"
+#include "bgpd/bgp_rd.h"
#include "bgpd/rfapi/rfapi.h"
#include "bgpd/rfapi/bgp_rfapi_cfg.h"
#if DEBUG_MONITOR_MOVE_SHORTER
{
- char buf[BUFSIZ];
+ char buf[PREFIX_STRLEN];
- prefix2str(&original_vpn_node->p, buf, BUFSIZ);
- buf[BUFSIZ - 1] = 0;
+ prefix2str(&original_vpn_node->p, buf, sizeof(buf));
vnc_zlog_debug_verbose("%s: called with node pfx=%s", __func__,
buf);
}
#if DEBUG_MONITOR_MOVE_SHORTER
{
- char buf[BUFSIZ];
+ char buf[PREFIX_STRLEN];
- prefix2str(&par->p, buf, BUFSIZ);
- buf[BUFSIZ - 1] = 0;
+ prefix2str(&par->p, buf, sizeof(buf));
vnc_zlog_debug_verbose("%s: moved to node pfx=%s", __func__,
buf);
}
__func__, __LINE__, have_vnc_tunnel_un);
#endif
- if (!have_vnc_tunnel_un && bi && bi->extra) {
+ if (!have_vnc_tunnel_un && bi->extra) {
/*
* use cached UN address from ENCAP route
*/
}
if (!skiplist_search(seen_nexthops, &pfx_vn, NULL)) {
#if DEBUG_RETURNED_NHL
- char buf[BUFSIZ];
+ char buf[PREFIX_STRLEN];
- prefix2str(&pfx_vn, buf, BUFSIZ);
- buf[BUFSIZ - 1] = 0; /* guarantee NUL-terminated */
+ prefix2str(&pfx_vn, buf, sizeof(buf));
vnc_zlog_debug_verbose(
"%s: already put VN/nexthop %s, skip", __func__,
buf);
#if DEBUG_RETURNED_NHL
{
- char buf[BUFSIZ];
+ char buf[PREFIX_STRLEN];
- prefix2str(&rn->p, buf, BUFSIZ);
- buf[BUFSIZ - 1] = 0;
+ prefix2str(&rn->p, buf, sizeof(buf));
vnc_zlog_debug_verbose("%s: called with node pfx=%s", __func__,
buf);
}
assert(bi->extra);
{
- char buf[BUFSIZ];
- prefix_rd2str(&bi->extra->vnc.import.rd, buf, BUFSIZ);
+ char buf[RD_ADDRSTRLEN];
+
vnc_zlog_debug_verbose("%s: bi %p, peer %p, rd %s", __func__,
- bi, bi->peer, buf);
+ bi, bi->peer,
+ prefix_rd2str(&bi->extra->vnc.import.rd,
+ buf, sizeof(buf)));
}
sl = RFAPI_RDINDEX_W_ALLOC(rn);
for (rc = skiplist_next(sl, (void **)&k, (void **)&v, &cursor); !rc;
rc = skiplist_next(sl, (void **)&k, (void **)&v, &cursor)) {
- char buf[BUFSIZ];
- char buf_aux_pfx[BUFSIZ];
+ char buf[RD_ADDRSTRLEN];
+ char buf_aux_pfx[PREFIX_STRLEN];
- prefix_rd2str(&k->extra->vnc.import.rd, buf, BUFSIZ);
- buf_aux_pfx[0] = 0;
+ prefix_rd2str(&k->extra->vnc.import.rd, buf, sizeof(buf));
if (k->extra->vnc.import.aux_prefix.family) {
prefix2str(&k->extra->vnc.import.aux_prefix,
- buf_aux_pfx, BUFSIZ);
- } else {
- strncpy(buf_aux_pfx, "(none)", BUFSIZ);
- buf_aux_pfx[BUFSIZ - 1] = 0;
- }
+ buf_aux_pfx, sizeof(buf_aux_pfx));
+ } else
+ strncpy(buf_aux_pfx, "(none)", PREFIX_STRLEN);
vnc_zlog_debug_verbose("bi %p, peer %p, rd %s, aux_prefix %s",
k, k->peer, buf, buf_aux_pfx);
#if DEBUG_BI_SEARCH
{
- char buf[BUFSIZ];
- char buf_aux_pfx[BUFSIZ];
+ char buf[RD_ADDRSTRLEN];
+ char buf_aux_pfx[PREFIX_STRLEN];
- prefix_rd2str(prd, buf, BUFSIZ);
if (aux_prefix) {
- prefix2str(aux_prefix, buf_aux_pfx, BUFSIZ);
- } else {
- strncpy(buf_aux_pfx, "(nil)", BUFSIZ - 1);
- buf_aux_pfx[BUFSIZ - 1] = 0;
- }
+ prefix2str(aux_prefix, buf_aux_pfx,
+ sizeof(buf_aux_pfx));
+ } else
+ strncpy(buf_aux_pfx, "(nil)", sizeof(buf_aux_pfx));
vnc_zlog_debug_verbose("%s want prd=%s, peer=%p, aux_prefix=%s",
- __func__, buf, peer, buf_aux_pfx);
+ __func__,
+ prefix_rd2str(prd, buf, sizeof(buf)),
+ peer, buf_aux_pfx);
rfapiItBiIndexDump(rn);
}
#endif
bi_result = bi_result->next) {
#if DEBUG_BI_SEARCH
{
- char buf[BUFSIZ];
- prefix_rd2str(&bi_result->extra->vnc.import.rd,
- buf, BUFSIZ);
+ char buf[RD_ADDRSTRLEN];
+
vnc_zlog_debug_verbose(
"%s: bi has prd=%s, peer=%p", __func__,
- buf, bi_result->peer);
+ prefix_rd2str(&bi_result->extra->vnc.import.rd,
+ buf,
+ sizeof(buf)),
+ bi_result->peer);
}
#endif
if (peer == bi_result->peer
int rc;
{
- char buf[BUFSIZ];
- prefix_rd2str(&bi->extra->vnc.import.rd, buf, BUFSIZ);
+ char buf[RD_ADDRSTRLEN];
+
vnc_zlog_debug_verbose("%s: bi %p, peer %p, rd %s", __func__,
- bi, bi->peer, buf);
+ bi, bi->peer,
+ prefix_rd2str(&bi->extra->vnc.import.rd,
+ buf, sizeof(buf)));
}
sl = RFAPI_RDINDEX(rn);
rfapiCopyUnEncap2VPN(ern->info, info_new);
route_unlock_node(ern); /* undo lock in route_note_match */
} else {
- char buf[BUFSIZ];
+ char buf[PREFIX_STRLEN];
+
prefix2str(&vn_prefix, buf, sizeof(buf));
- buf[BUFSIZ - 1] = 0;
/* Not a big deal, just means VPN route got here first */
vnc_zlog_debug_verbose("%s: no encap route for vn addr %s",
__func__, buf);
vnc_zlog_debug_verbose(
"%s: rfapiEcommunityGetLNI returned %d, lni=%d, attr=%p",
__func__, rc, lni, attr);
- if (attr && !rc) {
+ if (!rc) {
it = rfapiMacImportTableGet(bgp, lni);
rfapiBgpInfoFilteredImportVPN(
#if DEBUG_L2_EXTRA
{
- char buf_pfx[BUFSIZ];
+ char buf_pfx[PREFIX_STRLEN];
if (p) {
- prefix2str(p, buf_pfx, BUFSIZ);
+ prefix2str(p, buf_pfx, sizeof(buf_pfx));
} else {
buf_pfx[0] = '*';
buf_pfx[1] = 0;
struct bgp_info *next;
if (VNC_DEBUG(IMPORT_DEL_REMOTE)) {
- char p1line[BUFSIZ];
- char p2line[BUFSIZ];
+ char p1line[PREFIX_STRLEN];
+ char p2line[PREFIX_STRLEN];
- prefix2str(p, p1line, BUFSIZ);
- prefix2str(&rn->p, p2line, BUFSIZ);
+ prefix2str(p, p1line, sizeof(p1line));
+ prefix2str(&rn->p, p2line, sizeof(p2line));
vnc_zlog_debug_any("%s: want %s, have %s",
__func__, p1line, p2line);
}
continue;
{
- char buf_pfx[BUFSIZ];
- prefix2str(&rn->p, buf_pfx, BUFSIZ);
+ char buf_pfx[PREFIX_STRLEN];
+
+ prefix2str(&rn->p, buf_pfx, sizeof(buf_pfx));
vnc_zlog_debug_verbose("%s: rn pfx=%s",
__func__, buf_pfx);
}
struct bgp *bgp = bgp_get_default();
afi_t afi = family2afi(rn->p.family);
#if DEBUG_L2_EXTRA
- char buf_prefix[BUFSIZ];
+ char buf_prefix[PREFIX_STRLEN];
#endif
assert(bgp);
nves_seen = skiplist_new(0, NULL, NULL);
#if DEBUG_L2_EXTRA
- prefix2str(&it_node->p, buf_prefix, BUFSIZ);
+ prefix2str(&it_node->p, buf_prefix, sizeof(buf_prefix));
vnc_zlog_debug_verbose("%s: it=%p, it_node=%p, it_node->prefix=%s",
__func__, import_table, it_node, buf_prefix);
#endif
assert(!skiplist_insert(nves_seen,
m->rfd, NULL));
- {
- char buf_attach_pfx[BUFSIZ];
- char buf_target_pfx[BUFSIZ];
-
- prefix2str(&m->node->p,
- buf_attach_pfx,
- BUFSIZ);
- prefix2str(&m->p,
- buf_target_pfx,
- BUFSIZ);
- vnc_zlog_debug_verbose(
- "%s: update rfd %p attached to pfx %s (targ=%s)",
- __func__, m->rfd,
- buf_attach_pfx,
- buf_target_pfx);
- }
+ char buf_attach_pfx[PREFIX_STRLEN];
+ char buf_target_pfx[PREFIX_STRLEN];
+
+ prefix2str(&m->node->p,
+ buf_attach_pfx,
+ sizeof(buf_attach_pfx));
+ prefix2str(&m->p,
+ buf_target_pfx,
+ sizeof(buf_target_pfx));
+ vnc_zlog_debug_verbose(
+ "%s: update rfd %p attached to pfx %s (targ=%s)",
+ __func__, m->rfd,
+ buf_attach_pfx,
+ buf_target_pfx);
/*
* update its RIB
assert(rn);
#if DEBUG_L2_EXTRA
- char buf_prefix[BUFSIZ];
- prefix2str(&rn->p, buf_prefix, BUFSIZ);
+ char buf_prefix[PREFIX_STRLEN];
+
+ prefix2str(&rn->p, buf_prefix, sizeof(buf_prefix));
#endif
/*
}
}
- if (checkstats && bgp && bgp->rfapi) {
+ if (checkstats && bgp->rfapi) {
if (t_pfx_active != bgp->rfapi->rib_prefix_count_total) {
vnc_zlog_debug_verbose(
"%s: actual total pfx count %u != running %u",
{
struct thread *t = ri->timer;
struct rfapi_rib_tcb *tcb = NULL;
- char buf_prefix[BUFSIZ];
+ char buf_prefix[PREFIX_STRLEN];
if (t) {
tcb = t->arg;
UNSET_FLAG(tcb->flags, RFAPI_RIB_TCB_FLAG_DELETED);
}
- prefix2str(&rn->p, buf_prefix, BUFSIZ);
+ prefix2str(&rn->p, buf_prefix, sizeof(buf_prefix));
vnc_zlog_debug_verbose("%s: rfd %p pfx %s life %u", __func__, rfd,
buf_prefix, ri->lifetime);
ri->timer = NULL;
memcpy(&vo->v.l2addr.macaddr, bi->extra->vnc.import.rd.val + 2,
ETH_ALEN);
- if (bi->attr) {
- (void)rfapiEcommunityGetLNI(
- bi->attr->ecommunity,
- &vo->v.l2addr.logical_net_id);
- (void)rfapiEcommunityGetEthernetTag(
- bi->attr->ecommunity, &vo->v.l2addr.tag_id);
- }
+ (void)rfapiEcommunityGetLNI(bi->attr->ecommunity,
+ &vo->v.l2addr.logical_net_id);
+ (void)rfapiEcommunityGetEthernetTag(bi->attr->ecommunity,
+ &vo->v.l2addr.tag_id);
/* local_nve_id comes from RD */
vo->v.l2addr.local_nve_id = bi->extra->vnc.import.rd.val[1];
/*
* If there is an auxiliary IP address (L2 can have it), copy it
*/
- if (bi && bi->extra && bi->extra->vnc.import.aux_prefix.family) {
+ if (bi->extra && bi->extra->vnc.import.aux_prefix.family) {
ri->rk.aux_prefix = bi->extra->vnc.import.aux_prefix;
}
}
struct list *lPendCost = NULL;
struct list *delete_list = NULL;
int printedprefix = 0;
- char buf_prefix[BUFSIZ];
+ char buf_prefix[PREFIX_STRLEN];
int rib_node_started_nonempty = 0;
int sendingsomeroutes = 0;
#endif
assert(pn);
- prefix2str(&pn->p, buf_prefix, BUFSIZ);
+ prefix2str(&pn->p, buf_prefix, sizeof(buf_prefix));
vnc_zlog_debug_verbose("%s: afi=%d, %s pn->info=%p", __func__, afi,
buf_prefix, pn->info);
while (0
== skiplist_first(slRibPt, NULL, (void **)&ri)) {
- char buf[BUFSIZ];
- char buf2[BUFSIZ];
+ char buf[PREFIX_STRLEN];
+ char buf2[PREFIX_STRLEN];
listnode_add(delete_list, ri);
vnc_zlog_debug_verbose(
ri->timer = NULL;
}
- prefix2str(&ri->rk.vn, buf, BUFSIZ);
- prefix2str(&ri->un, buf2, BUFSIZ);
+ prefix2str(&ri->rk.vn, buf, sizeof(buf));
+ prefix2str(&ri->un, buf2, sizeof(buf2));
vnc_zlog_debug_verbose(
"%s: put dl pfx=%s vn=%s un=%s cost=%d life=%d vn_options=%p",
__func__, buf_prefix, buf, buf2,
} else {
- char buf_rd[BUFSIZ];
+ char buf_rd[RD_ADDRSTRLEN];
/* not found: add new route to RIB */
ori = rfapi_info_new();
ri->last_sent_time = rfapi_time(NULL);
#if DEBUG_RIB_SL_RD
{
- char buf_rd[BUFSIZ];
- prefix_rd2str(&ri->rk.rd,
- buf_rd,
- sizeof(buf_rd));
+ char buf_rd[RD_ADDRSTRLEN];
+
vnc_zlog_debug_verbose(
"%s: move route to recently deleted list, rd=%s",
- __func__, buf_rd);
+ __func__,
+ prefix_rd2str(&ri->rk.rd,
+ buf_rd,
+ sizeof(buf_rd)));
}
#endif
afi_t afi;
uint32_t queued_flag;
int count = 0;
- char buf[BUFSIZ];
+ char buf[PREFIX_STRLEN];
vnc_zlog_debug_verbose("%s: entry", __func__);
prefix = &it_node->p;
afi = family2afi(prefix->family);
- prefix2str(prefix, buf, BUFSIZ);
+ prefix2str(prefix, buf, sizeof(buf));
vnc_zlog_debug_verbose("%s: prefix=%s", __func__, buf);
pn = route_node_get(rfd->rib_pending[afi], prefix);
#if DEBUG_FTD_FILTER_RECENT
{
- char buf_pfx[BUFSIZ];
+ char buf_pfx[PREFIX_STRLEN];
- prefix2str(&it_rn->p, buf_pfx, BUFSIZ);
+ prefix2str(&it_rn->p, buf_pfx, sizeof(buf_pfx));
vnc_zlog_debug_verbose("%s: prefix %s", __func__, buf_pfx);
}
#endif
#if DEBUG_NHL
{
- char str_vn[BUFSIZ];
- char str_aux_prefix[BUFSIZ];
+ char str_vn[PREFIX_STRLEN];
+ char str_aux_prefix[PREFIX_STRLEN];
str_vn[0] = 0;
str_aux_prefix[0] = 0;
- prefix2str(&rk.vn, str_vn, BUFSIZ);
- prefix2str(&rk.aux_prefix, str_aux_prefix, BUFSIZ);
+ prefix2str(&rk.vn, str_vn, sizeof(str_vn));
+ prefix2str(&rk.aux_prefix, str_aux_prefix,
+ sizeof(str_aux_prefix));
if (!rk.aux_prefix.family) {
}
route_unlock_node(trn);
{
- char str_pfx[BUFSIZ];
- char str_pfx_vn[BUFSIZ];
+ char str_pfx[PREFIX_STRLEN];
+ char str_pfx_vn[PREFIX_STRLEN];
- prefix2str(&pfx, str_pfx, BUFSIZ);
- prefix2str(&rk.vn, str_pfx_vn, BUFSIZ);
+ prefix2str(&pfx, str_pfx, sizeof(str_pfx));
+ prefix2str(&rk.vn, str_pfx_vn, sizeof(str_pfx_vn));
vnc_zlog_debug_verbose(
"%s: added pfx=%s nh[vn]=%s, cost=%u, lifetime=%u, allowed=%d",
__func__, str_pfx, str_pfx_vn, nhp->prefix.cost,
{
struct rfapi_descriptor *rfd;
struct listnode *node;
- char buf[BUFSIZ];
+ char buf[PREFIX_STRLEN];
- prefix2str(&it_node->p, buf, BUFSIZ);
+ prefix2str(&it_node->p, buf, sizeof(buf));
vnc_zlog_debug_verbose("%s: entry, it=%p, afi=%d, it_node=%p, pfx=%s",
__func__, it, afi, it_node, buf);
for (rc = skiplist_next(sl, NULL, (void **)&ri, &cursor); !rc;
rc = skiplist_next(sl, NULL, (void **)&ri, &cursor)) {
- char str_vn[BUFSIZ];
- char str_un[BUFSIZ];
+ char str_vn[PREFIX_STRLEN];
+ char str_un[PREFIX_STRLEN];
char str_lifetime[BUFSIZ];
char str_age[BUFSIZ];
char *p;
- char str_rd[BUFSIZ];
+ char str_rd[RD_ADDRSTRLEN];
++routes_displayed;
- prefix2str(&ri->rk.vn, str_vn, BUFSIZ);
+ prefix2str(&ri->rk.vn, str_vn, sizeof(str_vn));
p = index(str_vn, '/');
if (p)
*p = 0;
- prefix2str(&ri->un, str_un, BUFSIZ);
+ prefix2str(&ri->un, str_un, sizeof(str_un));
p = index(str_un, '/');
if (p)
*p = 0;
str_rd[0] = 0; /* start empty */
#if DEBUG_RIB_SL_RD
- str_rd[0] = ' ';
- prefix_rd2str(&ri->rk.rd, str_rd + 1, BUFSIZ - 1);
+ prefix_rd2str(&ri->rk.rd, str_rd, sizeof(str_rd));
#endif
- fp(out, " %c %-20s %-15s %-15s %-4u %-8s %-8s%s\n",
+ fp(out, " %c %-20s %-15s %-15s %-4u %-8s %-8s %s\n",
deleted ? 'r' : ' ', *printedprefix ? "" : str_pfx, str_vn,
str_un, ri->cost, str_lifetime, str_age, str_rd);
const char *vty_newline;
int nhs_displayed = 0;
- char str_pfx[BUFSIZ];
+ char str_pfx[PREFIX_STRLEN];
int printedprefix = 0;
if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0)
return;
- prefix2str(pfx, str_pfx, BUFSIZ);
+ prefix2str(pfx, str_pfx, sizeof(str_pfx));
nhs_displayed +=
print_rib_sl(fp, vty, out, sl, 0, str_pfx, &printedprefix);
rn = route_next(rn)) {
struct skiplist *sl;
- char str_pfx[BUFSIZ];
+ char str_pfx[PREFIX_STRLEN];
int printedprefix = 0;
if (!show_removed)
str_un,
BUFSIZ));
}
- prefix2str(&rn->p, str_pfx, BUFSIZ);
+ prefix2str(&rn->p, str_pfx, sizeof(str_pfx));
// fp(out, " %s\n", buf); /* prefix */
routes_displayed++;
char buf_age[BUFSIZ];
- if (bi && bi->extra && bi->extra->vnc.import.create_time) {
+ if (bi->extra && bi->extra->vnc.import.create_time) {
rfapiFormatAge(bi->extra->vnc.import.create_time,
buf_age, BUFSIZ);
} else {
* print that on the next line
*/
- if (bi && bi->extra
+ if (bi->extra
&& bi->extra->vnc.import.aux_prefix.family) {
const char *sp;
void rfapiPrintRd(struct vty *vty, struct prefix_rd *prd)
{
- char buf[BUFSIZ];
+ char buf[RD_ADDRSTRLEN];
- buf[0] = 0;
- prefix_rd2str(prd, buf, BUFSIZ);
- buf[BUFSIZ - 1] = 0;
+ prefix_rd2str(prd, buf, sizeof(buf));
vty_out(vty, "%s", buf);
}
int rc;
afi_t afi;
struct rfapi_adb *adb;
- char buf[BUFSIZ];
+ char buf[PREFIX_STRLEN];
vty_out(vty, "%-10p ", rfd);
rfapiPrintRfapiIpAddr(vty, &rfd->un_addr);
if (family != adb->u.s.prefix_ip.family)
continue;
- prefix2str(&adb->u.s.prefix_ip, buf, BUFSIZ);
- buf[BUFSIZ - 1] = 0; /* guarantee NUL-terminated */
+ prefix2str(&adb->u.s.prefix_ip, buf, sizeof(buf));
vty_out(vty, " Adv Pfx: %s%s", buf, HVTYNL);
rfapiPrintAdvertisedInfo(vty, rfd, SAFI_MPLS_VPN,
rc == 0; rc = skiplist_next(rfd->advertised.ip0_by_ether, NULL,
(void **)&adb, &cursor)) {
- prefix2str(&adb->u.s.prefix_eth, buf, BUFSIZ);
- buf[BUFSIZ - 1] = 0; /* guarantee NUL-terminated */
+ prefix2str(&adb->u.s.prefix_eth, buf, sizeof(buf));
vty_out(vty, " Adv Pfx: %s%s", buf, HVTYNL);
continue;
{
- char prefixstr[BUFSIZ];
-
- prefixstr[0] = 0;
- inet_ntop(rn->p.family, &rn->p.u.prefix, prefixstr,
- BUFSIZ);
- vnc_zlog_debug_verbose("%s: checking prefix %s/%d",
- __func__, prefixstr,
- rn->p.prefixlen);
+ char prefixstr[PREFIX_STRLEN];
+
+ prefix2str(&rn->p, prefixstr, sizeof(prefixstr));
+ vnc_zlog_debug_verbose("%s: checking prefix %s",
+ __func__, prefixstr);
}
for (ri = rn->info; ri; ri = ri->next) {
continue;
{
- char prefixstr[BUFSIZ];
+ char prefixstr[PREFIX_STRLEN];
- prefixstr[0] = 0;
- inet_ntop(rn->p.family, &rn->p.u.prefix,
- prefixstr, BUFSIZ);
+ prefix2str(&rn->p, prefixstr,
+ sizeof(prefixstr));
vnc_zlog_debug_verbose(
- "%s: checking prefix %s/%d", __func__,
- prefixstr, rn->p.prefixlen);
+ "%s: checking prefix %s", __func__,
+ prefixstr);
}
/*
/* XXX uses secret knowledge of skiplist structure */
for (p = sl->header->forward[0]; p; p = p->forward[0]) {
- char kbuf[BUFSIZ];
- char hbuf[BUFSIZ];
- char ubuf[BUFSIZ];
+ char kbuf[PREFIX_STRLEN];
+ char hbuf[PREFIX_STRLEN];
+ char ubuf[PREFIX_STRLEN];
pb = p->value;
- prefix2str(p->key, kbuf, BUFSIZ);
- prefix2str(&pb->hpfx, hbuf, BUFSIZ);
- prefix2str(&pb->upfx, ubuf, BUFSIZ);
+ prefix2str(p->key, kbuf, sizeof(kbuf));
+ prefix2str(&pb->hpfx, hbuf, sizeof(hbuf));
+ prefix2str(&pb->upfx, ubuf, sizeof(ubuf));
vnc_zlog_debug_verbose(
"RHN Entry %d (q=%p): kpfx=%s, upfx=%s, hpfx=%s, ubi=%p",
* pfx */
assert(!vnc_prefix_cmp(&pb->hpfx, pkey));
if (vnc_prefix_cmp(&pb->hpfx, &pfx_orig_nexthop)) {
- char str_onh[BUFSIZ];
- char str_nve_pfx[BUFSIZ];
+ char str_onh[PREFIX_STRLEN];
+ char str_nve_pfx[PREFIX_STRLEN];
- prefix2str(&pfx_orig_nexthop, str_onh, BUFSIZ);
- str_onh[BUFSIZ - 1] = 0;
-
- prefix2str(&pb->hpfx, str_nve_pfx, BUFSIZ);
- str_nve_pfx[BUFSIZ - 1] = 0;
+ prefix2str(&pfx_orig_nexthop, str_onh, sizeof(str_onh));
+ prefix2str(&pb->hpfx, str_nve_pfx, sizeof(str_nve_pfx));
vnc_zlog_debug_verbose(
"%s: %s: FATAL: resolve_nve_nexthop list item bi nexthop %s != nve pfx %s",
return;
{
- char str_nh[BUFSIZ];
+ char str_nh[PREFIX_STRLEN];
- prefix2str(ubi_nexthop, str_nh, BUFSIZ);
- str_nh[BUFSIZ - 1] = 0;
+ prefix2str(ubi_nexthop, str_nh, sizeof(str_nh));
vnc_zlog_debug_verbose("%s: ubi_nexthop=%s", __func__, str_nh);
}
/*debugging */
if (VNC_DEBUG(VERBOSE)) {
- char str_pfx[BUFSIZ];
- char str_nh[BUFSIZ];
+ char str_pfx[PREFIX_STRLEN];
+ char str_nh[PREFIX_STRLEN];
struct prefix nh;
- prefix2str(prefix, str_pfx, BUFSIZ);
- str_pfx[BUFSIZ - 1] = 0;
+ prefix2str(prefix, str_pfx, sizeof(str_pfx));
nh.prefixlen = 0;
rfapiUnicastNexthop2Prefix(afi, info->attr, &nh);
if (nh.prefixlen) {
- prefix2str(&nh, str_nh, BUFSIZ);
- str_nh[BUFSIZ - 1] = 0;
+ prefix2str(&nh, str_nh, sizeof(str_nh));
} else {
str_nh[0] = '?';
str_nh[1] = 0;
uint32_t *med = NULL;
{
- char buf[BUFSIZ];
+ char buf[PREFIX_STRLEN];
- buf[0] = 0;
- prefix2str(prefix, buf, BUFSIZ);
- buf[BUFSIZ - 1] = 0;
+ prefix2str(prefix, buf, sizeof(buf));
vnc_zlog_debug_verbose("%s(prefix=%s) entry", __func__, buf);
}
}
if (VNC_DEBUG(IMPORT_BGP_ADD_ROUTE)) {
- char buf[BUFSIZ];
+ char buf[PREFIX_STRLEN];
- buf[0] = 0;
- prefix2str(vn_pfx, buf, BUFSIZ);
- buf[BUFSIZ - 1] = 0;
+ prefix2str(vn_pfx, buf, sizeof(buf));
vnc_zlog_debug_any("%s vn_pfx=%s", __func__, buf);
}
}
if (VNC_DEBUG(IMPORT_BGP_ADD_ROUTE)) {
- char buf[BUFSIZ];
+ char buf[PREFIX_STRLEN];
- buf[0] = 0;
- rfapiRfapiIpAddr2Str(&vnaddr, buf, BUFSIZ);
- buf[BUFSIZ - 1] = 0;
+ rfapiRfapiIpAddr2Str(&vnaddr, buf, sizeof(buf));
vnc_zlog_debug_any("%s: setting vnaddr to %s", __func__, buf);
}
uint32_t local_pref;
{
- char buf[BUFSIZ];
+ char buf[PREFIX_STRLEN];
- buf[0] = 0;
- prefix2str(prefix, buf, BUFSIZ);
- buf[BUFSIZ - 1] = 0;
+ prefix2str(prefix, buf, sizeof(buf));
vnc_zlog_debug_verbose("%s(prefix=%s) entry", __func__, buf);
}
}
if (VNC_DEBUG(IMPORT_BGP_ADD_ROUTE)) {
- char buf[BUFSIZ];
+ char buf[PREFIX_STRLEN];
- buf[0] = 0;
- prefix2str(vn_pfx, buf, BUFSIZ);
- buf[BUFSIZ - 1] = 0;
+ prefix2str(vn_pfx, buf, sizeof(buf));
vnc_zlog_debug_any("%s vn_pfx=%s", __func__, buf);
}
assert(afi);
- assert((rfg = bgp->rfapi_cfg->rfg_redist));
+ rfg = bgp->rfapi_cfg->rfg_redist;
+ assert(rfg);
/*
* Compute VN address
return;
{
- char str_nh[BUFSIZ];
-
- prefix2str(ubi_nexthop, str_nh, BUFSIZ);
- str_nh[BUFSIZ - 1] = 0;
+ char str_nh[PREFIX_STRLEN];
+ prefix2str(ubi_nexthop, str_nh, sizeof(str_nh));
vnc_zlog_debug_verbose("%s: ubi_nexthop=%s", __func__, str_nh);
}
return;
}
- if (bgp && bgp->rfapi)
+ if (bgp->rfapi)
sl = bgp->rfapi->resolve_nve_nexthop;
if (!sl) {
sizeof(struct prefix)); /* keep valgrind happy */
if (VNC_DEBUG(IMPORT_BGP_ADD_ROUTE)) {
- char hbuf[BUFSIZ];
- char ubuf[BUFSIZ];
+ char hbuf[PREFIX_STRLEN];
+ char ubuf[PREFIX_STRLEN];
- prefix2str(&pb->hpfx, hbuf, BUFSIZ);
- prefix2str(&pb->upfx, ubuf, BUFSIZ);
+ prefix2str(&pb->hpfx, hbuf, sizeof(hbuf));
+ prefix2str(&pb->upfx, ubuf, sizeof(ubuf));
vnc_zlog_debug_any(
"%s: examining RHN Entry (q=%p): upfx=%s, hpfx=%s, ubi=%p",
* Sanity check
*/
if (vnc_prefix_cmp(&pfx_unicast_nexthop, prefix)) {
- char str_unh[BUFSIZ];
- char str_nve_pfx[BUFSIZ];
+ char str_unh[PREFIX_STRLEN];
+ char str_nve_pfx[PREFIX_STRLEN];
- prefix2str(&pfx_unicast_nexthop, str_unh, BUFSIZ);
- str_unh[BUFSIZ - 1] = 0;
-
- prefix2str(prefix, str_nve_pfx, BUFSIZ);
- str_nve_pfx[BUFSIZ - 1] = 0;
+ prefix2str(&pfx_unicast_nexthop, str_unh,
+ sizeof(str_unh));
+ prefix2str(prefix, str_nve_pfx, sizeof(str_nve_pfx));
vnc_zlog_debug_verbose(
"%s: FATAL: resolve_nve_nexthop list item bi nexthop %s != nve pfx %s",
#if DEBUG_RHN_LIST
/* debug */
{
- char pbuf[BUFSIZ];
+ char pbuf[PREFIX_STRLEN];
- prefix2str(prefix, pbuf, BUFSIZ);
+ prefix2str(prefix, pbuf, sizeof(pbuf));
vnc_zlog_debug_verbose(
"%s: advancing past RHN Entry (q=%p): with prefix %s",
int rc;
{
- char str_pfx[BUFSIZ];
+ char str_pfx[PREFIX_STRLEN];
- prefix2str(prefix, str_pfx, BUFSIZ);
- str_pfx[BUFSIZ - 1] = 0;
+ prefix2str(prefix, str_pfx, sizeof(str_pfx));
vnc_zlog_debug_verbose("%s(bgp=%p, nve prefix=%s)", __func__,
bgp, str_pfx);
return;
}
- if (bgp && bgp->rfapi)
+ if (bgp->rfapi)
sl = bgp->rfapi->resolve_nve_nexthop;
if (!sl) {
* Sanity check
*/
if (vnc_prefix_cmp(&pfx_unicast_nexthop, prefix)) {
- char str_unh[BUFSIZ];
- char str_nve_pfx[BUFSIZ];
-
- prefix2str(&pfx_unicast_nexthop, str_unh, BUFSIZ);
- str_unh[BUFSIZ - 1] = 0;
+ char str_unh[PREFIX_STRLEN];
+ char str_nve_pfx[PREFIX_STRLEN];
- prefix2str(prefix, str_nve_pfx, BUFSIZ);
- str_nve_pfx[BUFSIZ - 1] = 0;
+ prefix2str(&pfx_unicast_nexthop, str_unh,
+ sizeof(str_unh));
+ prefix2str(prefix, str_nve_pfx, sizeof(str_nve_pfx));
vnc_zlog_debug_verbose(
"%s: FATAL: resolve_nve_nexthop list item bi nexthop %s != nve pfx %s",
/*debugging */
{
- char str_pfx[BUFSIZ];
-
- prefix2str(&rn_interior->p, str_pfx, BUFSIZ);
- str_pfx[BUFSIZ - 1] = 0;
+ char str_pfx[PREFIX_STRLEN];
+ prefix2str(&rn_interior->p, str_pfx, sizeof(str_pfx));
vnc_zlog_debug_verbose("%s: interior prefix=%s, bi type=%d",
__func__, str_pfx, bi_interior->type);
}
(void **)&pfx_exterior, &cursor)) {
struct prefix pfx_nexthop;
- char buf[BUFSIZ];
+ char buf[PREFIX_STRLEN];
afi_t afi_exterior = family2afi(pfx_exterior->family);
prefix2str(pfx_exterior, buf, sizeof(buf));
- buf[sizeof(buf) - 1] = 0;
vnc_zlog_debug_verbose(
"%s: checking exterior orphan at prefix %s", __func__,
buf);
/*debugging */
{
- char str_pfx[BUFSIZ];
+ char str_pfx[PREFIX_STRLEN];
- prefix2str(&rn_interior->p, str_pfx, BUFSIZ);
- str_pfx[BUFSIZ - 1] = 0;
+ prefix2str(&rn_interior->p, str_pfx, sizeof(str_pfx));
vnc_zlog_debug_verbose("%s: interior prefix=%s, bi type=%d",
__func__, str_pfx, bi_interior->type);
if (VNC_DEBUG(VERBOSE)) {
struct prefix pfx_nexthop;
- char buf[BUFSIZ];
- char buf_nh[BUFSIZ];
+ char buf[PREFIX_STRLEN];
+ char buf_nh[PREFIX_STRLEN];
- prefix2str(prefix, buf, BUFSIZ);
+ prefix2str(prefix, buf, sizeof(buf));
rfapiUnicastNexthop2Prefix(afi, info->attr, &pfx_nexthop);
- prefix2str(&pfx_nexthop, buf_nh, BUFSIZ);
+ prefix2str(&pfx_nexthop, buf_nh, sizeof(buf_nh));
vnc_zlog_debug_verbose("%s: pfx %s, nh %s", __func__, buf,
buf_nh);
{
struct prefix pfx_nexthop;
- char buf[BUFSIZ];
- char buf_nh[BUFSIZ];
+ char buf[PREFIX_STRLEN];
+ char buf_nh[PREFIX_STRLEN];
- prefix2str(prefix, buf, BUFSIZ);
+ prefix2str(prefix, buf, sizeof(buf));
rfapiUnicastNexthop2Prefix(afi, info->attr, &pfx_nexthop);
- prefix2str(&pfx_nexthop, buf_nh, BUFSIZ);
+ prefix2str(&pfx_nexthop, buf_nh, sizeof(buf_nh));
vnc_zlog_debug_verbose("%s: pfx %s, nh %s", __func__, buf,
buf_nh);
( CPPFLAGS="$HOST_CPPFLAGS"; \
CFLAGS="$HOST_CFLAGS"; \
LDFLAGS="$HOST_LDFLAGS"; \
- cd hosttools; "${abssrc}/configure" "--host=$build" "--build=$build"; )
+ cd hosttools; "${abssrc}/configure" "--host=$build" "--build=$build" "--enable-clippy-only" "--disable-nhrpd" "--disable-vtysh"; )
AC_MSG_NOTICE([...])
AC_MSG_NOTICE([... cross-compilation: finished self-configuring for build platform tools])
AS_HELP_STRING([--enable-logfile-mask=ARG], [set mask for log files]))
AC_ARG_ENABLE(shell_access,
AS_HELP_STRING([--enable-shell-access], [Allow users to access shell/telnet/ssh]))
+AC_ARG_ENABLE(realms,
+ AS_HELP_STRING([--enable-realms], [enable REALMS support under Linux]))
AC_ARG_ENABLE(rtadv,
AS_HELP_STRING([--disable-rtadv], [disable IPV6 router advertisement feature]))
AC_ARG_ENABLE(irdp,
AS_HELP_STRING([--enable-oldvpn-commands], [Keep old vpn commands]))
AC_ARG_ENABLE(rpki,
AS_HELP_STRING([--enable-rpki], [enable RPKI prefix validation support]))
+AC_ARG_ENABLE([clippy-only],
+ AS_HELP_STRING([--enable-clippy-only], [Only build clippy]))
+AS_IF([test "${enable_clippy_only}" != "yes"], [
AC_CHECK_HEADERS(json-c/json.h)
AC_CHECK_LIB(json-c, json_object_get, LIBS="$LIBS -ljson-c", [], [-lm])
if test $ac_cv_lib_json_c_json_object_get = no; then
AC_MSG_ERROR([lib json is needed to compile])
fi
fi
+])
AC_ARG_ENABLE([dev_build],
AS_HELP_STRING([--enable-dev-build], [build for development]))
AC_SYS_LARGEFILE
+dnl ------------------------
+dnl Integrated REALMS option
+dnl ------------------------
+if test "${enable_realms}" = "yes"; then
+ case "$host_os" in
+ linux*)
+ AC_DEFINE(SUPPORT_REALMS,, Realms support)
+ ;;
+ *)
+ echo "Sorry, only Linux has REALMS support"
+ exit 1
+ ;;
+ esac
+fi
+AM_CONDITIONAL([SUPPORT_REALMS], [test "${enable_realms}" = "yes"])
+
dnl ---------------------
dnl Integrated VTY option
dnl ---------------------
backports/ubuntu17.10/versionext \
frr-doc.docs frr-doc.info frr-doc.install \
frr-doc.lintian-overrides frr.conf \
+ frr-dbg.lintian-overrides \
frr.dirs frr.docs frr.install \
frr.lintian-overrides frr.logrotate \
frr.manpages frr.pam frr.postinst frr.postrm \
frr.dvi: $(frr_TEXINFOS) defines.texi
frr.html: $(frr_TEXINFOS) defines.texi
-frr_TEXINFOS = appendix.texi basic.texi bgpd.texi isisd.texi filter.texi \
+frr_TEXINFOS = \
+ appendix.texi \
+ basic.texi \
+ bgpd.texi \
+ isisd.texi \
+ filter.texi \
vnc.texi \
babeld.texi \
- install.texi ipv6.texi kernel.texi main.texi \
+ install.texi \
+ ipv6.texi \
+ kernel.texi \
+ main.texi \
nhrpd.texi \
eigrpd.texi \
- ospf6d.texi ospfd.texi \
- overview.texi protocol.texi ripd.texi ripngd.texi routemap.texi \
- snmp.texi vtysh.texi routeserver.texi $(figures_png) \
- snmptrap.texi ospf_fundamentals.texi isisd.texi $(figures_txt) \
- rpki.texi
+ ospf6d.texi \
+ ospfd.texi \
+ overview.texi \
+ protocol.texi \
+ ripd.texi \
+ ripngd.texi \
+ routemap.texi \
+ snmp.texi \
+ vtysh.texi \
+ routeserver.texi \
+ $(figures_png) \
+ snmptrap.texi \
+ ospf_fundamentals.texi \
+ isisd.texi $(figures_txt) \
+ rpki.texi \
+ pimd.texi \
+ #END
.png.eps:
$(PNGTOEPS) $< "$@"
@item --enable-multipath=@var{ARG}
Enable support for Equal Cost Multipath. @var{ARG} is the maximum number
of ECMP paths to allow, set to 0 to allow unlimited number of paths.
+@item --enable-realms
+Enable the support of linux Realms. Convert tag values from 1-255
+into a realm value when inserting into the linux kernel. Then
+routing policy can be assigned to the realm. See the tc man page.
@item --disable-rtadv
Disable support IPV6 router advertisement in zebra.
@item --enable-gcc-rdynamic
--- /dev/null
+@c -*-texinfo-*-
+@c This is part of the Frr Manual.
+@c @value{COPYRIGHT_STR}
+@c See file frr.texi for copying conditions.
+@node PIM
+@chapter PIM
+
+PIM -- Protocol Independent Multicast
+
+@command{pimd} supports pim-sm as well as igmp v2 and v3. pim is
+vrf aware and can work within the context of vrf's in order to
+do S,G mrouting.
+
+@menu
+* Starting and Stopping pimd::
+* PIM Configuration::
+* PIM Interface Configuration::
+* PIM Multicast RIB insertion::
+* Show PIM Information::
+* PIM Debug Commands::
+@end menu
+
+@node Starting and Stopping pimd
+@section Starting and Stopping pimd
+
+The default configuration file name of @command{pimd}'s is
+@file{pimd.conf}. When invocation @command{pimd} searches directory
+@value{INSTALL_PREFIX_ETC}. If @file{pimd.conf} is not there
+then next search current directory.
+
+@command{pimd} requires zebra for proper operation. Additionally
+@command{pimd} depends on routing properly setup and working
+in the network that it is working on.
+
+@example
+@group
+# zebra -d
+# pimd -d
+@end group
+@end example
+
+Please note that @command{zebra} must be invoked before @command{pimd}.
+
+To stop @command{pimd}. Please use @command{kill `cat
+/var/run/pimd.pid`}. Certain signals have special meanings to @command{pimd}.
+
+@table @samp
+@item SIGUSR1
+Rotate @command{pimd} logfile.
+@item SIGINT
+@itemx SIGTERM
+@command{pimd} sweeps all installed PIM mroutes then terminates properly.
+@end table
+
+@command{pimd} invocation options. Common options that can be specified
+(@pxref{Common Invocation Options}).
+
+@node PIM Configuration
+
+@deffn Command {ip pim rp A.B.C.D A.B.C.D/M} {}
+In order to use pim, it is necessary to configure a RP for join
+messages to be sent to. Currently the only methodology to
+do this is via static rp commands. All routers in the
+pim network must agree on these values. The first ip address
+is the RP's address and the second value is the matching
+prefix of group ranges covered. This command is vrf aware,
+to configure for a vrf, enter the vrf submode.
+@end deffn
+
+@deffn Command {ip pim spt-switchover infinity-and-beyond} {}
+On the last hop router if it is desired to not switch over
+to the SPT tree. Configure this command. This command is
+vrf aware, to configure for a vrf, enter the vrf submode.
+#end deffn
+
+@deffn Comand {ip pim ecmp} {}
+If pim has the a choice of ECMP nexthops for a particular
+RPF, pim will cause S,G flows to be spread out amongst
+the nexthops. If this command is not specified then
+the first nexthop found will be used. This command
+is vrf aware, to configure for a vrf, enter the vrf submode.
+@end deffn
+
+@deffn Command {ip pim ecmp rebalance} {}
+If pim is using ECMP and an interface goes down, cause
+pim to rebalance all S,G flows aross the remaining
+nexthops. If this command is not configured pim only
+modifies those S,G flows that were using the interface
+that went down. This command is vrf aware, to configure
+for a vrf, enter the vrf submode.
+@end deffn
+
+@deffn Command {ip pim join-prune-interval (60-600)} {}
+Modify the join/prune interval that pim uses to the
+new value. Time is specified in seconds. This command
+is vrf aware, to configure for a vrf, enter the vrf submode.
+@end deffn
+
+@deffn Command {ip pim keep-alive-timer (31-60000)} {}
+Modify the time out value for a S,G flow from 31-60000
+seconds. 31 seconds is choosen for a lower bound
+because some hardware platforms cannot see data flowing
+in better than 30 second chunks. This comand is vrf
+aware, to configure for a vrf, enter the vrf submode.
+@end deffn
+
+@deffn Command {ip pim packets (1-100)} {}
+When processing packets from a neighbor process the
+number of packets incoming at one time before moving
+on to the next task. The default value is 3 packets.
+This command is only useful at scale when you can
+possibly have a large number of pim control packets
+flowing. This command is vrf aware, to configure for
+a vrf, enter the vrf submode.
+@end deffn
+
+@deffn Command {ip pim register-suppress-time (5-60000)} {}
+Modify the time that pim will register suppress a FHR
+will send register notifications to the kernel. This command
+is vrf aware, to configure for a vrf, enter the vrf submode.
+@end deffn
+
+@deffn Command {ip pim send-v6-secondary} {}
+When sending pim hello packets tell pim to send
+any v6 secondary addresses on the interface. This
+information is used to allow pim to use v6 nexthops
+in it's decision for RPF lookup. This command
+is vrf aware, to configure for a vrf, enter the vrf submode.
+@end deffn
+
+@deffn Command {ip pim ssm prefix-list WORD} {}
+Specify a range of group addresses via a prefix-list
+that forces pim to never do SM over. This command
+is vrf aware, to configure for a vrf, enter the vrf submode.
+@end deffn
+
+@deffn Command {ip multicast rpf-lookup-mode WORD} {}
+Modify how PIM does RPF lookups in the zebra routing table.
+You can use these choices:
+@table @lookup_modes
+@item longer-prefix
+Lookup the RPF in both tables using the longer prefix as a match
+@item lower-distance
+Lookup the RPF in both tables using the lower distance as a match
+@item mrib-only
+Lookup in the Multicast RIB only
+@item mrib-then-urib
+Lookup in the Multicast RIB then the Unicast Rib, returning first found.
+This is the default value for lookup if this command is not entered
+@item urib-only
+Lookup in the Unicast Rib only.
+@end table
+@end deffn
+
+@node PIM Interface Configuration
+@section PIM Interface Configuration
+
+PIM interface commands allow you to configure an
+interface as either a Receiver or a interface
+that you would like to form pim neighbors on. If the
+interface is in a vrf, enter the interface command with
+the vrf keyword at the end.
+
+@deffn {PIM Interface Command] {ip pim bfd} {}
+Turns on BFD support for PIM for this interface.
+@end deffn
+
+@deffn {PIM Interface Command} {ip pim drpriority (1-4294967295)} {}
+Set the DR Priority for the interface. This command is useful
+to allow the user to influence what node becomes the DR for a
+lan segment.
+@end deffn
+
+@deffn {PIM Interface Command} {ip pim hello (1-180) (1-180)} {}
+Set the pim hello and hold interval for a interface.
+@end deffn
+
+@deffn {PIM Interface Command} {ip pim sm} {}
+Tell pim that we would like to use this interface to form
+pim neighbors over. Please note we will *not* accept
+igmp reports over this interface with this command.
+@end deffn
+
+@deffn {PIM Interface Command} {ip igmp} {}
+Tell pim to receive IGMP reports and Query on this
+interface. The default version is v3. This command
+is useful on the LHR.
+@end deffn
+
+@deffn {PIM Interface Command} {ip igmp query-interval (1-1800)} {}
+Set the IGMP query interval that PIM will use.
+@end deffn
+
+@deffn {PIM Interface Command} {ip igmp query-max-response-time (10-250)} {}
+Set the IGMP query response timeout value. If an report is not returned
+in the specified time we will assume the S,G or *,G has timed out.
+@end deffn
+
+@deffn {PIM Interface Command} {ip igmp version (2-3)} {}
+Set the IGMP version used on this interface. The default value
+is 3.
+@end deffn
+
+@deffn {PIM Interface Command} {ip multicat boundary oil WORD} {}
+Set a pim multicast boundary, based upon the WORD prefix-list. If
+a pim join or IGMP report is received on this interface and the Group
+is denyed by the prefix-list, PIM will ignore the join or report.
+@end deffn
+
+@node PIM Multicast RIB insertion::
+@section PIM Multicast RIB insertion::
+
+In order to influence Multicast RPF lookup, it is possible to insert
+into zebra routes for the Multicast RIB. These routes are only
+used for RPF lookup and will not be used by zebra for insertion
+into the kernel *or* for normal rib processing. As such it is
+possible to create weird states with these commands. Use with
+caution. Most of the time this will not be necessary.
+
+@deffn {PIM Multicast RIB insertion} {ip mroute A.B.C.D/M A.B.C.D (1-255)} {}
+Insert into the Multicast Rib Route A.B.C.D/M with specified nexthop. The distance can be specified as well if desired.
+@end deffn
+
+@deffn {PIM Multicast RIB insertion} {ip mroute A.B.C.D/M INTERFACE (1-255)} {}
+Insert into the Multicast Rib Route A.B.C.D/M using the specified INTERFACE.
+The distance can be specified as well if desired.
+@end deffn
+
+@node Show PIM Information::
+@section Show PIM Information
+
+All PIM show commands are vrf aware and typically allow you to insert
+a specified vrf command if information is desired about a specific vrf.
+If no vrf is specified then the default vrf is assumed. Finally
+the special keyword 'all' allows you to look at all vrfs for the command.
+Naming a vrf 'all' will cause great confusion.
+
+@deffn {Show PIM Information} {show ip multicast}
+Display various information about the interfaces used in this pim
+instance.
+@end deffn
+
+@deffn {Show PIM Information} {show ip mroute}
+Display information about installed into the kernel S,G mroutes.
+@end deffn
+
+@deffn {Show PIM Information} {show ip mroute count}
+Display information about installed into the kernel S,G mroutes
+and in addition display data about packet flow for the mroutes.
+@end deffn
+
+@deffn {Show PIM Information} {show ip pim assert}
+Display information about asserts in the PIM system for S,G mroutes.
+@end deffn
+
+@deffn {Show PIM Information} {show ip pim assert-internal}
+Display internal assert state for S,G mroutes
+@end deffn
+
+@deffn {Show PIM Information} {show ip pim assert-metric}
+Display metric information about assert state for S,G mroutes
+@end deffn
+
+@deffn {Show PIM Information} {show ip pim assert-winner-metric}
+Display winner metric for assert state for S,G mroutes
+@end deffn
+
+@deffn {Show PIM Information} {show ip pim group-type}
+Display SSM group ranges
+@end deffn
+
+@deffn {Show PIM Information} {show ip pim interface}
+Display information about interfaces PIM is using.
+@end deffn
+
+@deffn {Show PIM Information} {show ip pim join}
+Display information about PIM joins received.
+@end deffn
+
+@deffn {Show PIM Information} {show ip pim local-membership} {}
+Display information about PIM interface local-membership
+@end deffn
+
+@deffn {Show PIM Information} {show ip pim neighbor} {}
+Display information about PIM neighbors
+@end deffn
+
+@deffn {Show PIM Information} {show ip pim nexthop} {}
+Display information about pim nexthops that are being
+used
+@end deffn
+
+@deffn {Show PIM Information} {show ip pim nexthop-lookup} {}
+Display information about a S,G pair and how the RPF would
+be choosen. This is especially useful if there are ECMP's
+available from the RPF lookup.
+@end deffn
+
+@deffn {Show PIM Information} {show ip pim rp-info} {}
+Display information about RP's that are configured on
+this router
+@end deffn
+
+@deffn {Show PIM Information} {show ip pim rpf} {}
+Display information about currently being used S,G's
+and their RPF lookup information. Additionally display
+some statistics about what has been happening on the
+router
+@end deffn
+
+@deffn {show PIM Information} {show ip pim secondary} {}
+Display information about an interface and all the
+secondary addresses associated with it
+@end deffn
+
+@deffn {show PIM Information} {show ip pim state} {}
+Display information about known S,G's and incoming
+interface as well as the OIL and how they were choosen
+@end deffn
+
+@deffn {show PIM Information} {show ip pim upstream} {}
+Display upstream information about a S,G mroute
+@end deffn
+
+@deffn {show PIM Information} {show ip pim upstream-join-desired} {}
+Display upstream information for S,G's and if we desire to
+join the mcast tree
+@end deffn
+
+@deffn {show PIM Information} {show ip pim upstream-rpf} {}
+Display upstream information for S,G's and the RPF data
+associated with them
+@end deffn
+
+@deffn {show PIM Information} {show ip rpf} {}
+Display the multicast RIB created in zebra
+@end deffn
+
+@node PIM Debug Commands
+@section PIM Debug Commands
+
+The debugging subsystem for PIM behaves in accordance with how FRR handles debugging. You can specify debugging at the enable cli mode as well as the configure cli mode. If you specify debug commands in the configuration cli mode, the debug commands can be persistent across restarts of the FRR pimd if the config was written out.
+
+@deffn {PIM Debug Commands} {debug pim events}
+This turns on debugging for PIM system events. Especially timers.
+@end deffn
+
+@deffn {PIM Debug Commands} {debug pim nht}
+This turns on debugging for PIM nexthop tracking. It will display information about RPF lookups and information about when a nexthop changes.
+@end deffn
+
+@deffn {PIM Debug Commands} {debug pim packet-dump}
+This turns on an extraordinary amount of data. Each pim packet sent and received is dumped for debugging purposes. This should be considered a developer only command
+@end deffn
+
+@deffn {PIM Debug Commands} {debug pim packets}
+This turns on information about packet generation for sending and about packet handling from a received packet
+@end deffn
+
+@deffn {PIM Debug Commands} {debug pim trace}
+This traces pim code and how it is running.
+@end deffn
+
+@deffn {PIM Debug Commands} {debug pim zebra}
+This gathers data about events from zebra that come up through the zapi
+@end deffn
Matches the specified @var{metric}.
@end deffn
+@deffn {Route-map Command} {match tag @var{tag}} {}
+Matches the specified tag value associated with the route.
+This tag value can be in the range of (1-4294967295).
+@end deffn
+
@deffn {Route-map Command} {match local-preference @var{metric}} {}
Matches the specified @var{local-preference}.
@end deffn
@node Route Map Set Command
@section Route Map Set Command
+@deffn {Route-map Command} {set tag @var{tag}} {}
+Set a tag on the matched route. This tag value can be from
+(1-4294967295). Additionally if you have compiled with
+the --enable-realms configure option. Tag values from (1-255)
+are sent to the linux kernel as a realm value. Then route
+policy can be applied. See the tc man page.
+@end deffn
+
@deffn {Route-map Command} {set ip next-hop @var{ipv4_address}} {}
Set the BGP nexthop address.
@end deffn
*/
if (!dest) {
char buf[PREFIX_STRLEN];
+
zlog_err("%s: Received prefix %s which we do not know about",
__PRETTY_FUNCTION__,
- prefix2str(&dest_addr, buf, strlen(buf)));
+ prefix2str(&dest_addr, buf, sizeof(buf)));
+ eigrp_IPv4_InternalTLV_free(tlv);
continue;
}
circuit->lsp_queue = list_new();
circuit->lsp_hash = isis_lsp_hash_new();
- circuit->lsp_queue_last_push = monotime(NULL);
+ circuit->lsp_queue_last_push[0] = circuit->lsp_queue_last_push[1] =
+ 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 */
- time_t lsp_queue_last_push; /* timestamp used to enforce transmit
+ time_t lsp_queue_last_push[2]; /* timestamp used to enforce transmit
* interval;
* for scalability, use one timestamp per
* circuit, instead of one per lsp per
if (!circuit->lsp_queue)
continue;
- if (now - circuit->lsp_queue_last_push
+ if (now - circuit->lsp_queue_last_push[level]
< MIN_LSP_RETRANS_INTERVAL) {
continue;
}
- circuit->lsp_queue_last_push = now;
+ circuit->lsp_queue_last_push[level] = now;
for (ALL_LIST_ELEMENTS_RO(
lsp_list, lspnode, lsp)) {
}
static int isis_run_spf(struct isis_area *area, int level, int family,
- u_char *sysid)
+ u_char *sysid, struct timeval *nowtv)
{
int retval = ISIS_OK;
struct isis_vertex *vertex;
uint16_t mtid;
/* Get time that can't roll backwards. */
- monotime(&time_now);
- start_time = time_now.tv_sec;
- start_time = (start_time * 1000000) + time_now.tv_usec;
+ start_time = nowtv->tv_sec;
+ start_time = (start_time * 1000000) + nowtv->tv_usec;
if (family == AF_INET)
spftree = area->spftree[level - 1];
area->area_tag, level);
if (area->ip_circuits)
- retval = isis_run_spf(area, level, AF_INET, isis->sysid);
+ retval = isis_run_spf(area, level, AF_INET, isis->sysid,
+ &thread->real);
if (area->ipv6_circuits)
- retval = isis_run_spf(area, level, AF_INET6, isis->sysid);
+ retval = isis_run_spf(area, level, AF_INET6, isis->sysid,
+ &thread->real);
return retval;
}
timer, &area->spf_timer[level - 1]);
if (isis->debugs & DEBUG_SPF_EVENTS)
- zlog_debug("ISIS-Spf (%s) L%d SPF scheduled %d sec from now",
- area->area_tag, level,
- area->min_spf_interval[level - 1] - diff);
+ zlog_debug("ISIS-Spf (%s) L%d SPF scheduled %ld sec from now",
+ area->area_tag, level, timer);
return ISIS_OK;
}
if (dir_str[0] == 'r') {
if (negate)
- DEBUG_OFF(hello, HELLO_RECV);
+ DEBUG_OFF(hello, LDP_DEBUG_HELLO_RECV);
else
- DEBUG_ON(hello, HELLO_RECV);
+ DEBUG_ON(hello, LDP_DEBUG_HELLO_RECV);
} else {
if (negate)
- DEBUG_OFF(hello, HELLO_SEND);
+ DEBUG_OFF(hello, LDP_DEBUG_HELLO_SEND);
else
- DEBUG_ON(hello, HELLO_SEND);
+ DEBUG_ON(hello, LDP_DEBUG_HELLO_SEND);
}
} else if (strcmp(type_str, "errors") == 0) {
if (negate)
- DEBUG_OFF(errors, ERRORS);
+ DEBUG_OFF(errors, LDP_DEBUG_ERRORS);
else
- DEBUG_ON(errors, ERRORS);
+ DEBUG_ON(errors, LDP_DEBUG_ERRORS);
} else if (strcmp(type_str, "event") == 0) {
if (negate)
- DEBUG_OFF(event, EVENT);
+ DEBUG_OFF(event, LDP_DEBUG_EVENT);
else
- DEBUG_ON(event, EVENT);
+ DEBUG_ON(event, LDP_DEBUG_EVENT);
} else if (strcmp(type_str, "labels") == 0) {
if (negate)
- DEBUG_OFF(labels, LABELS);
+ DEBUG_OFF(labels, LDP_DEBUG_LABELS);
else
- DEBUG_ON(labels, LABELS);
+ DEBUG_ON(labels, LDP_DEBUG_LABELS);
} else if (strcmp(type_str, "messages") == 0) {
if (dir_str == NULL)
return (CMD_WARNING_CONFIG_FAILED);
if (dir_str[0] == 'r') {
if (negate) {
- DEBUG_OFF(msg, MSG_RECV);
- DEBUG_OFF(msg, MSG_RECV_ALL);
+ DEBUG_OFF(msg, LDP_DEBUG_MSG_RECV);
+ DEBUG_OFF(msg, LDP_DEBUG_MSG_RECV_ALL);
} else {
- DEBUG_ON(msg, MSG_RECV);
+ DEBUG_ON(msg, LDP_DEBUG_MSG_RECV);
if (all)
- DEBUG_ON(msg, MSG_RECV_ALL);
+ DEBUG_ON(msg, LDP_DEBUG_MSG_RECV_ALL);
}
} else {
if (negate) {
- DEBUG_OFF(msg, MSG_SEND);
- DEBUG_OFF(msg, MSG_SEND_ALL);
+ DEBUG_OFF(msg, LDP_DEBUG_MSG_SEND);
+ DEBUG_OFF(msg, LDP_DEBUG_MSG_SEND_ALL);
} else {
- DEBUG_ON(msg, MSG_SEND);
+ DEBUG_ON(msg, LDP_DEBUG_MSG_SEND);
if (all)
- DEBUG_ON(msg, MSG_SEND_ALL);
+ DEBUG_ON(msg, LDP_DEBUG_MSG_SEND_ALL);
}
}
} else if (strcmp(type_str, "zebra") == 0) {
if (negate)
- DEBUG_OFF(zebra, ZEBRA);
+ DEBUG_OFF(zebra, LDP_DEBUG_ZEBRA);
else
- DEBUG_ON(zebra, ZEBRA);
+ DEBUG_ON(zebra, LDP_DEBUG_ZEBRA);
}
main_imsg_compose_both(IMSG_DEBUG_UPDATE, &ldp_debug,
{
vty_out (vty, "LDP debugging status:\n");
- if (LDP_DEBUG(hello, HELLO_RECV))
+ if (LDP_DEBUG(hello, LDP_DEBUG_HELLO_RECV))
vty_out (vty," LDP discovery debugging is on (inbound)\n");
- if (LDP_DEBUG(hello, HELLO_SEND))
+ if (LDP_DEBUG(hello, LDP_DEBUG_HELLO_SEND))
vty_out (vty," LDP discovery debugging is on (outbound)\n");
- if (LDP_DEBUG(errors, ERRORS))
+ if (LDP_DEBUG(errors, LDP_DEBUG_ERRORS))
vty_out (vty, " LDP errors debugging is on\n");
- if (LDP_DEBUG(event, EVENT))
+ if (LDP_DEBUG(event, LDP_DEBUG_EVENT))
vty_out (vty, " LDP events debugging is on\n");
- if (LDP_DEBUG(labels, LABELS))
+ if (LDP_DEBUG(labels, LDP_DEBUG_LABELS))
vty_out (vty, " LDP labels debugging is on\n");
- if (LDP_DEBUG(msg, MSG_RECV_ALL))
+ if (LDP_DEBUG(msg, LDP_DEBUG_MSG_RECV_ALL))
vty_out (vty,
" LDP detailed messages debugging is on (inbound)\n");
- else if (LDP_DEBUG(msg, MSG_RECV))
+ else if (LDP_DEBUG(msg, LDP_DEBUG_MSG_RECV))
vty_out (vty," LDP messages debugging is on (inbound)\n");
- if (LDP_DEBUG(msg, MSG_SEND_ALL))
+ if (LDP_DEBUG(msg, LDP_DEBUG_MSG_SEND_ALL))
vty_out (vty,
" LDP detailed messages debugging is on (outbound)\n");
- else if (LDP_DEBUG(msg, MSG_SEND))
+ else if (LDP_DEBUG(msg, LDP_DEBUG_MSG_SEND))
vty_out (vty," LDP messages debugging is on (outbound)\n");
- if (LDP_DEBUG(zebra, ZEBRA))
+ if (LDP_DEBUG(zebra, LDP_DEBUG_ZEBRA))
vty_out (vty, " LDP zebra debugging is on\n");
vty_out (vty, "\n");
{
int write = 0;
- if (CONF_LDP_DEBUG(hello, HELLO_RECV)) {
+ if (CONF_LDP_DEBUG(hello, LDP_DEBUG_HELLO_RECV)) {
vty_out (vty,"debug mpls ldp discovery hello recv\n");
write = 1;
}
- if (CONF_LDP_DEBUG(hello, HELLO_SEND)) {
+ if (CONF_LDP_DEBUG(hello, LDP_DEBUG_HELLO_SEND)) {
vty_out (vty,"debug mpls ldp discovery hello sent\n");
write = 1;
}
- if (CONF_LDP_DEBUG(errors, ERRORS)) {
+ if (CONF_LDP_DEBUG(errors, LDP_DEBUG_ERRORS)) {
vty_out (vty, "debug mpls ldp errors\n");
write = 1;
}
- if (CONF_LDP_DEBUG(event, EVENT)) {
+ if (CONF_LDP_DEBUG(event, LDP_DEBUG_EVENT)) {
vty_out (vty, "debug mpls ldp event\n");
write = 1;
}
- if (CONF_LDP_DEBUG(labels, LABELS)) {
+ if (CONF_LDP_DEBUG(labels, LDP_DEBUG_LABELS)) {
vty_out (vty, "debug mpls ldp labels\n");
write = 1;
}
- if (CONF_LDP_DEBUG(msg, MSG_RECV_ALL)) {
+ if (CONF_LDP_DEBUG(msg, LDP_DEBUG_MSG_RECV_ALL)) {
vty_out (vty, "debug mpls ldp messages recv all\n");
write = 1;
- } else if (CONF_LDP_DEBUG(msg, MSG_RECV)) {
+ } else if (CONF_LDP_DEBUG(msg, LDP_DEBUG_MSG_RECV)) {
vty_out (vty, "debug mpls ldp messages recv\n");
write = 1;
}
- if (CONF_LDP_DEBUG(msg, MSG_SEND_ALL)) {
+ if (CONF_LDP_DEBUG(msg, LDP_DEBUG_MSG_SEND_ALL)) {
vty_out (vty, "debug mpls ldp messages sent all\n");
write = 1;
- } else if (CONF_LDP_DEBUG(msg, MSG_SEND)) {
+ } else if (CONF_LDP_DEBUG(msg, LDP_DEBUG_MSG_SEND)) {
vty_out (vty, "debug mpls ldp messages sent\n");
write = 1;
}
- if (CONF_LDP_DEBUG(zebra, ZEBRA)) {
+ if (CONF_LDP_DEBUG(zebra, LDP_DEBUG_ZEBRA)) {
vty_out (vty, "debug mpls ldp zebra\n");
write = 1;
}
extern struct ldp_debug conf_ldp_debug;
extern struct ldp_debug ldp_debug;
-#define CONF_DEBUG_ON(a, b) (conf_ldp_debug.a |= (LDP_DEBUG_ ## b))
-#define CONF_DEBUG_OFF(a, b) (conf_ldp_debug.a &= ~(LDP_DEBUG_ ## b))
+#define CONF_DEBUG_ON(a, b) (conf_ldp_debug.a |= (b))
+#define CONF_DEBUG_OFF(a, b) (conf_ldp_debug.a &= ~(b))
-#define TERM_DEBUG_ON(a, b) (ldp_debug.a |= (LDP_DEBUG_ ## b))
-#define TERM_DEBUG_OFF(a, b) (ldp_debug.a &= ~(LDP_DEBUG_ ## b))
+#define TERM_DEBUG_ON(a, b) (ldp_debug.a |= (b))
+#define TERM_DEBUG_OFF(a, b) (ldp_debug.a &= ~(b))
#define DEBUG_ON(a, b) \
do { \
TERM_DEBUG_OFF(a, b); \
} while (0)
-#define LDP_DEBUG(a, b) (ldp_debug.a & LDP_DEBUG_ ## b)
-#define CONF_LDP_DEBUG(a, b) (conf_ldp_debug.a & LDP_DEBUG_ ## b)
+#define LDP_DEBUG(a, b) (ldp_debug.a & b)
+#define CONF_LDP_DEBUG(a, b) (conf_ldp_debug.a & b)
#define debug_hello_recv(emsg, ...) \
do { \
- if (LDP_DEBUG(hello, HELLO_RECV)) \
+ if (LDP_DEBUG(hello, LDP_DEBUG_HELLO_RECV)) \
log_debug("discovery[recv]: " emsg, __VA_ARGS__); \
} while (0)
#define debug_hello_send(emsg, ...) \
do { \
- if (LDP_DEBUG(hello, HELLO_SEND)) \
+ if (LDP_DEBUG(hello, LDP_DEBUG_HELLO_SEND)) \
log_debug("discovery[send]: " emsg, __VA_ARGS__); \
} while (0)
#define debug_err(emsg, ...) \
do { \
- if (LDP_DEBUG(errors, ERRORS)) \
+ if (LDP_DEBUG(errors, LDP_DEBUG_ERRORS)) \
log_debug("error: " emsg, __VA_ARGS__); \
} while (0)
#define debug_evt(emsg, ...) \
do { \
- if (LDP_DEBUG(event, EVENT)) \
+ if (LDP_DEBUG(event, LDP_DEBUG_EVENT)) \
log_debug("event: " emsg, __VA_ARGS__); \
} while (0)
#define debug_labels(emsg, ...) \
do { \
- if (LDP_DEBUG(labels, LABELS)) \
+ if (LDP_DEBUG(labels, LDP_DEBUG_LABELS)) \
log_debug("labels: " emsg, __VA_ARGS__); \
} while (0)
#define debug_msg_recv(emsg, ...) \
do { \
- if (LDP_DEBUG(msg, MSG_RECV)) \
+ if (LDP_DEBUG(msg, LDP_DEBUG_MSG_RECV)) \
log_debug("msg[in]: " emsg, __VA_ARGS__); \
} while (0)
#define debug_msg_send(emsg, ...) \
do { \
- if (LDP_DEBUG(msg, MSG_SEND)) \
+ if (LDP_DEBUG(msg, LDP_DEBUG_MSG_SEND)) \
log_debug("msg[out]: " emsg, __VA_ARGS__); \
} while (0)
#define debug_kalive_recv(emsg, ...) \
do { \
- if (LDP_DEBUG(msg, MSG_RECV_ALL)) \
+ if (LDP_DEBUG(msg, LDP_DEBUG_MSG_RECV_ALL)) \
log_debug("kalive[in]: " emsg, __VA_ARGS__); \
} while (0)
#define debug_kalive_send(emsg, ...) \
do { \
- if (LDP_DEBUG(msg, MSG_SEND_ALL)) \
+ if (LDP_DEBUG(msg, LDP_DEBUG_MSG_SEND_ALL)) \
log_debug("kalive[out]: " emsg, __VA_ARGS__); \
} while (0)
#define debug_zebra_in(emsg, ...) \
do { \
- if (LDP_DEBUG(zebra, ZEBRA)) \
+ if (LDP_DEBUG(zebra, LDP_DEBUG_ZEBRA)) \
log_debug("zebra[in]: " emsg, __VA_ARGS__); \
} while (0)
#define debug_zebra_out(emsg, ...) \
do { \
- if (LDP_DEBUG(zebra, ZEBRA)) \
+ if (LDP_DEBUG(zebra, LDP_DEBUG_ZEBRA)) \
log_debug("zebra[out]: " emsg, __VA_ARGS__); \
} while (0)
}
}
-/* read callback integration */
-struct frrzmq_cb {
- struct thread *thread;
- void *zmqsock;
- void *arg;
- int fd;
-
- bool cancelled;
-
- void (*cb_msg)(void *arg, void *zmqsock);
- void (*cb_part)(void *arg, void *zmqsock,
- zmq_msg_t *msg, unsigned partnum);
-};
-
-
static int frrzmq_read_msg(struct thread *t)
{
- struct frrzmq_cb *cb = THREAD_ARG(t);
+ struct frrzmq_cb **cbp = THREAD_ARG(t);
+ struct frrzmq_cb *cb;
zmq_msg_t msg;
unsigned partno;
+ unsigned char read = 0;
int ret, more;
size_t moresz;
+ if (!cbp)
+ return 1;
+ cb = (*cbp);
+ if (!cb || !cb->zmqsock)
+ return 1;
+
while (1) {
- zmq_pollitem_t polli = {
- .socket = cb->zmqsock,
- .events = ZMQ_POLLIN
- };
+ zmq_pollitem_t polli = {.socket = cb->zmqsock,
+ .events = ZMQ_POLLIN};
ret = zmq_poll(&polli, 1, 0);
if (ret < 0)
goto out_err;
+
if (!(polli.revents & ZMQ_POLLIN))
break;
- if (cb->cb_msg) {
- cb->cb_msg(cb->arg, cb->zmqsock);
+ if (cb->read.cb_msg) {
+ cb->read.cb_msg(cb->read.arg, cb->zmqsock);
+ read = 1;
- if (cb->cancelled) {
- XFREE(MTYPE_ZEROMQ_CB, cb);
+ if (cb->read.cancelled) {
+ frrzmq_check_events(cbp, &cb->write,
+ ZMQ_POLLOUT);
+ cb->read.thread = NULL;
+ if (cb->write.cancelled && !cb->write.thread)
+ XFREE(MTYPE_ZEROMQ_CB, cb);
return 0;
}
continue;
zmq_msg_close(&msg);
goto out_err;
}
+ read = 1;
- cb->cb_part(cb->arg, cb->zmqsock, &msg, partno);
- if (cb->cancelled) {
+ cb->read.cb_part(cb->read.arg, cb->zmqsock, &msg,
+ partno);
+ if (cb->read.cancelled) {
zmq_msg_close(&msg);
- XFREE(MTYPE_ZEROMQ_CB, cb);
+ frrzmq_check_events(cbp, &cb->write,
+ ZMQ_POLLOUT);
+ cb->read.thread = NULL;
+ if (cb->write.cancelled && !cb->write.thread)
+ XFREE(MTYPE_ZEROMQ_CB, cb);
return 0;
}
* message; don't use zmq_msg_more here */
moresz = sizeof(more);
more = 0;
- ret = zmq_getsockopt(cb->zmqsock, ZMQ_RCVMORE,
- &more, &moresz);
+ ret = zmq_getsockopt(cb->zmqsock, ZMQ_RCVMORE, &more,
+ &moresz);
if (ret < 0) {
zmq_msg_close(&msg);
goto out_err;
zmq_msg_close(&msg);
}
- funcname_thread_add_read_write(THREAD_READ, t->master, frrzmq_read_msg,
- cb, cb->fd, &cb->thread, t->funcname, t->schedfrom,
- t->schedfrom_line);
+ if (read)
+ frrzmq_check_events(cbp, &cb->write, ZMQ_POLLOUT);
+
+ funcname_thread_add_read_write(
+ THREAD_READ, t->master, frrzmq_read_msg, cbp, cb->fd,
+ &cb->read.thread, t->funcname, t->schedfrom, t->schedfrom_line);
return 0;
out_err:
- zlog_err("ZeroMQ error: %s(%d)", strerror (errno), errno);
- return 0;
+ zlog_err("ZeroMQ read error: %s(%d)", strerror(errno), errno);
+ if (cb->read.cb_error)
+ cb->read.cb_error(cb->read.arg, cb->zmqsock);
+ return 1;
}
-struct frrzmq_cb *funcname_frrzmq_thread_add_read(
- struct thread_master *master,
- void (*msgfunc)(void *arg, void *zmqsock),
- void (*partfunc)(void *arg, void *zmqsock,
- zmq_msg_t *msg, unsigned partnum),
- void *arg, void *zmqsock, debugargdef)
+int funcname_frrzmq_thread_add_read(struct thread_master *master,
+ void (*msgfunc)(void *arg, void *zmqsock),
+ void (*partfunc)(void *arg, void *zmqsock,
+ zmq_msg_t *msg,
+ unsigned partnum),
+ void (*errfunc)(void *arg, void *zmqsock),
+ void *arg, void *zmqsock,
+ struct frrzmq_cb **cbp, debugargdef)
{
int fd, events;
size_t len;
struct frrzmq_cb *cb;
+ if (!cbp)
+ return -1;
if (!(msgfunc || partfunc) || (msgfunc && partfunc))
- return NULL;
+ return -1;
+ len = sizeof(fd);
+ if (zmq_getsockopt(zmqsock, ZMQ_FD, &fd, &len))
+ return -1;
+ len = sizeof(events);
+ if (zmq_getsockopt(zmqsock, ZMQ_EVENTS, &events, &len))
+ return -1;
+
+ if (*cbp)
+ cb = *cbp;
+ else {
+ cb = XCALLOC(MTYPE_ZEROMQ_CB, sizeof(struct frrzmq_cb));
+ cb->write.cancelled = 1;
+ if (!cb)
+ return -1;
+ *cbp = cb;
+ }
+
+ cb->zmqsock = zmqsock;
+ cb->fd = fd;
+ cb->read.arg = arg;
+ cb->read.cb_msg = msgfunc;
+ cb->read.cb_part = partfunc;
+ cb->read.cb_error = errfunc;
+ cb->read.cancelled = 0;
+
+ if (events & ZMQ_POLLIN) {
+ if (cb->read.thread) {
+ thread_cancel(cb->read.thread);
+ cb->read.thread = NULL;
+ }
+ funcname_thread_add_event(master, frrzmq_read_msg, cbp, fd,
+ &cb->read.thread, funcname, schedfrom,
+ fromln);
+ } else
+ funcname_thread_add_read_write(
+ THREAD_READ, master, frrzmq_read_msg, cbp, fd,
+ &cb->read.thread, funcname, schedfrom, fromln);
+ return 0;
+}
+
+static int frrzmq_write_msg(struct thread *t)
+{
+ struct frrzmq_cb **cbp = THREAD_ARG(t);
+ struct frrzmq_cb *cb;
+ unsigned char written = 0;
+ int ret;
+
+ if (!cbp)
+ return 1;
+ cb = (*cbp);
+ if (!cb || !cb->zmqsock)
+ return 1;
+
+ while (1) {
+ zmq_pollitem_t polli = {.socket = cb->zmqsock,
+ .events = ZMQ_POLLOUT};
+ ret = zmq_poll(&polli, 1, 0);
+
+ if (ret < 0)
+ goto out_err;
+
+ if (!(polli.revents & ZMQ_POLLOUT))
+ break;
+
+ if (cb->write.cb_msg) {
+ cb->write.cb_msg(cb->write.arg, cb->zmqsock);
+ written = 1;
+
+ if (cb->write.cancelled) {
+ frrzmq_check_events(cbp, &cb->read, ZMQ_POLLIN);
+ cb->write.thread = NULL;
+ if (cb->read.cancelled && !cb->read.thread)
+ XFREE(MTYPE_ZEROMQ_CB, cb);
+ return 0;
+ }
+ continue;
+ }
+ }
+
+ if (written)
+ frrzmq_check_events(cbp, &cb->read, ZMQ_POLLIN);
+
+ funcname_thread_add_read_write(THREAD_WRITE, t->master,
+ frrzmq_write_msg, cbp, cb->fd,
+ &cb->write.thread, t->funcname,
+ t->schedfrom, t->schedfrom_line);
+ return 0;
+
+out_err:
+ zlog_err("ZeroMQ write error: %s(%d)", strerror(errno), errno);
+ if (cb->write.cb_error)
+ cb->write.cb_error(cb->write.arg, cb->zmqsock);
+ return 1;
+}
+int funcname_frrzmq_thread_add_write(struct thread_master *master,
+ void (*msgfunc)(void *arg, void *zmqsock),
+ void (*errfunc)(void *arg, void *zmqsock),
+ void *arg, void *zmqsock,
+ struct frrzmq_cb **cbp, debugargdef)
+{
+ int fd, events;
+ size_t len;
+ struct frrzmq_cb *cb;
+
+ if (!cbp)
+ return -1;
+ if (!msgfunc)
+ return -1;
len = sizeof(fd);
if (zmq_getsockopt(zmqsock, ZMQ_FD, &fd, &len))
- return NULL;
+ return -1;
len = sizeof(events);
if (zmq_getsockopt(zmqsock, ZMQ_EVENTS, &events, &len))
- return NULL;
+ return -1;
- cb = XCALLOC(MTYPE_ZEROMQ_CB, sizeof(struct frrzmq_cb));
- if (!cb)
- return NULL;
+ if (*cbp)
+ cb = *cbp;
+ else {
+ cb = XCALLOC(MTYPE_ZEROMQ_CB, sizeof(struct frrzmq_cb));
+ cb->read.cancelled = 1;
+ if (!cb)
+ return -1;
+ *cbp = cb;
+ }
- cb->arg = arg;
cb->zmqsock = zmqsock;
- cb->cb_msg = msgfunc;
- cb->cb_part = partfunc;
cb->fd = fd;
+ cb->write.arg = arg;
+ cb->write.cb_msg = msgfunc;
+ cb->write.cb_part = NULL;
+ cb->write.cb_error = errfunc;
+ cb->write.cancelled = 0;
+
+ if (events & ZMQ_POLLOUT) {
+ if (cb->write.thread) {
+ thread_cancel(cb->write.thread);
+ cb->write.thread = NULL;
+ }
+ funcname_thread_add_event(master, frrzmq_write_msg, cbp, fd,
+ &cb->write.thread, funcname,
+ schedfrom, fromln);
+ } else
+ funcname_thread_add_read_write(
+ THREAD_WRITE, master, frrzmq_write_msg, cbp, fd,
+ &cb->write.thread, funcname, schedfrom, fromln);
+ return 0;
+}
- if (events & ZMQ_POLLIN)
- funcname_thread_add_event(master,
- frrzmq_read_msg, cb, fd, &cb->thread,
- funcname, schedfrom, fromln);
- else
- funcname_thread_add_read_write(THREAD_READ, master,
- frrzmq_read_msg, cb, fd, &cb->thread,
- funcname, schedfrom, fromln);
- return cb;
+void frrzmq_thread_cancel(struct frrzmq_cb **cb, struct cb_core *core)
+{
+ if (!cb || !*cb)
+ return;
+ core->cancelled = 1;
+ if (core->thread) {
+ thread_cancel(core->thread);
+ core->thread = NULL;
+ }
+ if ((*cb)->read.cancelled && !(*cb)->read.thread
+ && (*cb)->write.cancelled && (*cb)->write.thread)
+ XFREE(MTYPE_ZEROMQ_CB, *cb);
}
-void frrzmq_thread_cancel(struct frrzmq_cb *cb)
+void frrzmq_check_events(struct frrzmq_cb **cbp, struct cb_core *core,
+ int event)
{
- if (!cb->thread) {
- /* canceling from within callback */
- cb->cancelled = 1;
+ struct frrzmq_cb *cb;
+ int events;
+ size_t len;
+
+ if (!cbp)
+ return;
+ cb = (*cbp);
+ if (!cb || !cb->zmqsock)
+ return;
+
+ if (zmq_getsockopt(cb->zmqsock, ZMQ_EVENTS, &events, &len))
return;
+ if (events & event && core->thread && !core->cancelled) {
+ struct thread_master *tm = core->thread->master;
+ thread_cancel(core->thread);
+ core->thread = NULL;
+ thread_add_event(tm, (event == ZMQ_POLLIN ? frrzmq_read_msg
+ : frrzmq_write_msg),
+ cbp, cb->fd, &core->thread);
}
- thread_cancel(cb->thread);
- XFREE(MTYPE_ZEROMQ_CB, cb);
}
* foo_LDFLAGS = libfrrzmq.la libfrr.la $(ZEROMQ_LIBS)
*/
+/* callback integration */
+struct cb_core {
+ struct thread *thread;
+ void *arg;
+
+ bool cancelled;
+
+ void (*cb_msg)(void *arg, void *zmqsock);
+ void (*cb_part)(void *arg, void *zmqsock, zmq_msg_t *msg,
+ unsigned partnum);
+ void (*cb_error)(void *arg, void *zmqsock);
+};
+struct frrzmq_cb {
+ void *zmqsock;
+ int fd;
+
+ struct cb_core read;
+ struct cb_core write;
+};
+
/* libzmq's context
*
* this is mostly here as a convenience, it has IPv6 enabled but nothing
*/
extern void *frrzmq_context;
-extern void frrzmq_init (void);
-extern void frrzmq_finish (void);
+extern void frrzmq_init(void);
+extern void frrzmq_finish(void);
#define debugargdef const char *funcname, const char *schedfrom, int fromln
/* core event registration, one of these 2 macros should be used */
-#define frrzmq_thread_add_read_msg(m,f,a,z) funcname_frrzmq_thread_add_read( \
- m,f,NULL,a,z,#f,__FILE__,__LINE__)
-#define frrzmq_thread_add_read_part(m,f,a,z) funcname_frrzmq_thread_add_read( \
- m,NULL,f,a,z,#f,__FILE__,__LINE__)
+#define frrzmq_thread_add_read_msg(m, f, e, a, z, d) \
+ funcname_frrzmq_thread_add_read(m, f, NULL, e, a, z, d, #f, __FILE__, \
+ __LINE__)
+#define frrzmq_thread_add_read_part(m, f, e, a, z, d) \
+ funcname_frrzmq_thread_add_read(m, NULL, f, e, a, z, d, #f, __FILE__, \
+ __LINE__)
+#define frrzmq_thread_add_write_msg(m, f, e, a, z, d) \
+ funcname_frrzmq_thread_add_write(m, f, e, a, z, d, #f, __FILE__, \
+ __LINE__)
+struct cb_core;
struct frrzmq_cb;
-/* Set up a POLLIN notification to be called from the libfrr main loop.
- * This has the following properties:
+/* Set up a POLLIN or POLLOUT notification to be called from the libfrr main
+ * loop. This has the following properties:
*
* - since ZeroMQ works with edge triggered notifications, it will loop and
* dispatch as many events as ZeroMQ has pending at the time libfrr calls
* - if partfunc is specified, the message is read and partfunc is called
* for each ZeroMQ multi-part subpart. Note that you can't send replies
* before all parts have been read because that violates the ZeroMQ FSM.
+ * - write version doesn't allow for partial callback, you must handle the
+ * whole message (all parts) in msgfunc callback
* - you can safely cancel the callback from within itself
* - installing a callback will check for pending events (ZMQ_EVENTS) and
* may schedule the event to run as soon as libfrr is back in its main
* loop.
+ */
+extern int funcname_frrzmq_thread_add_read(
+ struct thread_master *master, void (*msgfunc)(void *arg, void *zmqsock),
+ void (*partfunc)(void *arg, void *zmqsock, zmq_msg_t *msg,
+ unsigned partnum),
+ void (*errfunc)(void *arg, void *zmqsock), void *arg, void *zmqsock,
+ struct frrzmq_cb **cb, debugargdef);
+extern int funcname_frrzmq_thread_add_write(
+ struct thread_master *master, void (*msgfunc)(void *arg, void *zmqsock),
+ void (*errfunc)(void *arg, void *zmqsock), void *arg, void *zmqsock,
+ struct frrzmq_cb **cb, debugargdef);
+
+extern void frrzmq_thread_cancel(struct frrzmq_cb **cb, struct cb_core *core);
+
+/*
+ * http://api.zeromq.org/4-2:zmq-getsockopt#toc10
*
- * TODO #1: add ZMQ_POLLERR / error callback
- * TODO #2: add frrzmq_check_events() function to check for edge triggered
- * things that may have happened after a zmq_send() call or so
+ * As the descriptor is edge triggered, applications must update the state of
+ * ZMQ_EVENTS after each invocation of zmq_send or zmq_recv.To be more explicit:
+ * after calling zmq_send the socket may become readable (and vice versa)
+ * without triggering a read event on the file descriptor.
*/
-extern struct frrzmq_cb *funcname_frrzmq_thread_add_read(
- struct thread_master *master,
- void (*msgfunc)(void *arg, void *zmqsock),
- void (*partfunc)(void *arg, void *zmqsock,
- zmq_msg_t *msg, unsigned partnum),
- void *arg, void *zmqsock, debugargdef);
-
-extern void frrzmq_thread_cancel(struct frrzmq_cb *cb);
+extern void frrzmq_check_events(struct frrzmq_cb **cbp, struct cb_core *core,
+ int event);
#endif /* _FRRZMQ_H */
return 0;
}
+int ptm_lib_cleanup_msg(ptm_lib_handle_t *hdl, void *ctxt)
+{
+ ptm_lib_msg_ctxt_t *p_ctxt = ctxt;
+ csv_t *csv;
+
+ if (!p_ctxt) {
+ ERRLOG("%s: no context \n", __FUNCTION__);
+ return -1;
+ }
+
+ csv = p_ctxt->csv;
+
+ csv_clean(csv);
+ csv_free(csv);
+ free(p_ctxt);
+
+ return 0;
+}
+
int ptm_lib_complete_msg(ptm_lib_handle_t *hdl, void *ctxt, char *buf, int *len)
{
ptm_lib_msg_ctxt_t *p_ctxt = ctxt;
int ptm_lib_init_msg(ptm_lib_handle_t *, int, int, void *, void **);
int ptm_lib_append_msg(ptm_lib_handle_t *, void *, const char *, const char *);
int ptm_lib_complete_msg(ptm_lib_handle_t *, void *, char *, int *);
+int ptm_lib_cleanup_msg(ptm_lib_handle_t *, void *);
#endif
{
struct listnode *anode, *bnode;
struct ospf6_nexthop *anh, *bnh;
+ bool identical = false;
if (a && b) {
if (listcount(a->nh_list) == listcount(b->nh_list)) {
for (ALL_LIST_ELEMENTS_RO(a->nh_list, anode, anh)) {
+ identical = false;
for (ALL_LIST_ELEMENTS_RO(b->nh_list, bnode,
- bnh))
- if (!ospf6_nexthop_is_same(anh, bnh))
- return (1);
+ bnh)) {
+ if (ospf6_nexthop_is_same(anh, bnh))
+ identical = true;
+ }
+ /* Currnet List A element not found List B
+ * Non-Identical lists return */
+ if (identical == false)
+ return 1;
}
- return (0);
+ return 0;
} else
- return (1);
+ return 1;
}
/* One of the routes doesn't exist ? */
return (1);
static int ospf6_nexthop_cmp(struct ospf6_nexthop *a, struct ospf6_nexthop *b)
{
- if ((a)->ifindex == (b)->ifindex &&
- IN6_ARE_ADDR_EQUAL(&(a)->address, &(b)->address))
+ if (a->ifindex < b->ifindex)
+ return -1;
+ else if (a->ifindex > b->ifindex)
return 1;
+ else
+ return memcmp(&a->address, &b->address,
+ sizeof(struct in6_addr));
+
return 0;
}
if (len)
id = htonl(*offset);
offset += len;
- offsetlen -= len;
+ //offsetlen -= len; // Add back in if we need it again
if (exact) {
if (v->magic & OSPFv3WWASTABLE) {
len = (offsetlen < 1 ? 0 : 1);
if (len)
instid = *offset;
- offset += len;
- offsetlen -= len;
+ //offset += len; // Add back in if we ever start using again
+ //offsetlen -= len;
if (exact) {
oi = ospf6_interface_lookup_by_ifindex(ifindex);
len = (offsetlen < 1 ? 0 : 1);
if (len)
rtrid = htonl(*offset);
- offset += len;
- offsetlen -= len;
+ //offset += len; // Add back in if we ever start looking at data
+ //offsetlen -= len;
if (exact) {
oi = ospf6_interface_lookup_by_ifindex(ifindex);
{
VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
int idx_ipv4 = 2;
- struct interface *ifp;
+ struct interface *ifp = NULL;
struct in_addr addr = {.s_addr = INADDR_ANY};
int ret;
struct ospf_if_params *params;
ospf_passive_interface_default(ospf, OSPF_IF_PASSIVE);
return CMD_SUCCESS;
}
+ if (ospf->vrf_id != VRF_UNKNOWN)
+ ifp = if_get_by_name(argv[1]->arg, ospf->vrf_id, 0);
- ifp = if_get_by_name(argv[1]->arg, ospf->vrf_id, 0);
if (ifp == NULL) {
vty_out(vty, "interface %s not found.\n",
(char *)argv[1]->arg);
- return CMD_WARNING;
+ return CMD_WARNING_CONFIG_FAILED;
}
params = IF_DEF_PARAMS(ifp);
{
VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
int idx_ipv4 = 3;
- struct interface *ifp;
+ struct interface *ifp = NULL;
struct in_addr addr = {.s_addr = INADDR_ANY};
struct ospf_if_params *params;
int ret;
return CMD_SUCCESS;
}
- ifp = if_get_by_name(argv[2]->arg, ospf->vrf_id, 0);
+ if (ospf->vrf_id != VRF_UNKNOWN)
+ ifp = if_get_by_name(argv[1]->arg, ospf->vrf_id, 0);
+
if (ifp == NULL) {
vty_out(vty, "interface %s not found.\n",
(char *)argv[1]->arg);
- return CMD_WARNING;
+ return CMD_WARNING_CONFIG_FAILED;
}
params = IF_DEF_PARAMS(ifp);
if (!pim_ifp->sec_addr_list) {
zlog_err("%s: failure: secondary addresslist",
__PRETTY_FUNCTION__);
+ return if_list_clean(pim_ifp);
}
pim_ifp->sec_addr_list->del = (void (*)(void *))pim_sec_addr_free;
pim_ifp->sec_addr_list->cmp =
ch = THREAD_ARG(t);
+ if (PIM_DEBUG_TRACE)
+ zlog_debug("%s: IFCHANNEL%s %s Prune Pending Timer Popped",
+ __PRETTY_FUNCTION__,
+ pim_str_sg_dump(&ch->sg),
+ pim_ifchannel_ifjoin_name(ch->ifjoin_state,
+ ch->flags));
+
if (ch->ifjoin_state == PIM_IFJOIN_PRUNE_PENDING) {
ifp = ch->interface;
pim_ifp = ifp->info;
* message on RP path upon prune timer expiry.
*/
ch->ifjoin_state = PIM_IFJOIN_PRUNE;
- if (ch->upstream)
+ if (ch->upstream) {
+ struct pim_upstream *parent =
+ ch->upstream->parent;
+
pim_upstream_update_join_desired(pim_ifp->pim,
ch->upstream);
+
+ pim_jp_agg_single_upstream_send(&parent->rpf,
+ parent,
+ true);
+ }
}
/* from here ch may have been deleted */
- } else {
- zlog_warn(
- "%s: IFCHANNEL%s Prune Pending Timer Popped while in %s state",
- __PRETTY_FUNCTION__, pim_str_sg_dump(&ch->sg),
- pim_ifchannel_ifjoin_name(ch->ifjoin_state, ch->flags));
}
return 0;
#include "frr_zmq.h"
DEFINE_MTYPE_STATIC(LIB, TESTBUF, "zmq test buffer")
+DEFINE_MTYPE_STATIC(LIB, ZMQMSG, "zmq message")
static struct thread_master *master;
XFREE(MTYPE_TESTBUF, data);
}
+static int recv_delim(void *zmqsock)
+{
+ /* receive delim */
+ zmq_msg_t zdelim;
+ int more;
+ zmq_msg_init(&zdelim);
+ zmq_msg_recv(&zdelim, zmqsock, 0);
+ more = zmq_msg_more(&zdelim);
+ zmq_msg_close(&zdelim);
+ return more;
+}
+static void send_delim(void *zmqsock)
+{
+ /* Send delim */
+ zmq_msg_t zdelim;
+ zmq_msg_init(&zdelim);
+ zmq_msg_send(&zdelim, zmqsock, ZMQ_SNDMORE);
+ zmq_msg_close(&zdelim);
+}
static void run_client(int syncfd)
{
int i, j;
char dummy;
void *zmqctx = NULL;
void *zmqsock;
+ int more;
read(syncfd, &dummy, 1);
zmqctx = zmq_ctx_new();
zmq_ctx_set(zmqctx, ZMQ_IPV6, 1);
- zmqsock = zmq_socket(zmqctx, ZMQ_REQ);
+ zmqsock = zmq_socket(zmqctx, ZMQ_DEALER);
if (zmq_connect(zmqsock, "tcp://127.0.0.1:17171")) {
perror("zmq_connect");
exit(1);
/* single-part */
for (i = 0; i < 8; i++) {
- snprintf(buf, sizeof(buf), "msg #%d %c%c%c",
- i, 'a' + i, 'b' + i, 'c' + i);
+ snprintf(buf, sizeof(buf), "msg #%d %c%c%c", i, 'a' + i,
+ 'b' + i, 'c' + i);
printf("client send: %s\n", buf);
fflush(stdout);
- zmq_send(zmqsock, buf, strlen(buf) + 1, 0);
- zmq_recv(zmqsock, buf, sizeof(buf), 0);
- printf("client recv: %s\n", buf);
+ send_delim(zmqsock);
+ zmq_send(zmqsock, buf, strlen(buf) + 1, 0);
+ more = recv_delim(zmqsock);
+ while (more) {
+ zmq_recv(zmqsock, buf, sizeof(buf), 0);
+ printf("client recv: %s\n", buf);
+ size_t len = sizeof(more);
+ if (zmq_getsockopt(zmqsock, ZMQ_RCVMORE, &more, &len))
+ break;
+ }
}
/* multipart */
for (i = 2; i < 5; i++) {
- int more;
-
printf("---\n");
+ send_delim(zmqsock);
+ zmq_msg_t part;
for (j = 1; j <= i; j++) {
- zmq_msg_t part;
char *dyn = XMALLOC(MTYPE_TESTBUF, 32);
snprintf(dyn, 32, "part %d/%d", j, i);
zmq_msg_send(&part, zmqsock, j < i ? ZMQ_SNDMORE : 0);
}
- zmq_msg_t part;
+ recv_delim(zmqsock);
do {
char *data;
} while (more);
zmq_msg_close(&part);
}
+
+ /* write callback */
+ printf("---\n");
+ snprintf(buf, 32, "Done receiving");
+ printf("client send: %s\n", buf);
+ fflush(stdout);
+ send_delim(zmqsock);
+ zmq_send(zmqsock, buf, strlen(buf) + 1, 0);
+ /* wait for message from server */
+ more = recv_delim(zmqsock);
+ while (more) {
+ zmq_recv(zmqsock, buf, sizeof(buf), 0);
+ printf("client recv: %s\n", buf);
+ size_t len = sizeof(more);
+ if (zmq_getsockopt(zmqsock, ZMQ_RCVMORE, &more, &len))
+ break;
+ }
+
zmq_close(zmqsock);
zmq_ctx_term(zmqctx);
}
static struct frrzmq_cb *cb;
+static void recv_id_and_delim(void *zmqsock, zmq_msg_t *msg_id)
+{
+ /* receive id */
+ zmq_msg_init(msg_id);
+ zmq_msg_recv(msg_id, zmqsock, 0);
+ /* receive delim */
+ recv_delim(zmqsock);
+}
+static void send_id_and_delim(void *zmqsock, zmq_msg_t *msg_id)
+{
+ /* Send Id */
+ zmq_msg_send(msg_id, zmqsock, ZMQ_SNDMORE);
+ send_delim(zmqsock);
+}
+static void serverwritefn(void *arg, void *zmqsock)
+{
+ zmq_msg_t *msg_id = (zmq_msg_t *)arg;
+ char buf[32] = "Test write callback";
+ size_t i;
+
+ for (i = 0; i < strlen(buf); i++)
+ buf[i] = toupper(buf[i]);
+ printf("server send: %s\n", buf);
+ fflush(stdout);
+ send_id_and_delim(zmqsock, msg_id);
+ zmq_send(zmqsock, buf, strlen(buf) + 1, 0);
+
+ /* send just once */
+ frrzmq_thread_cancel(&cb, &cb->write);
+
+ zmq_msg_close(msg_id);
+ XFREE(MTYPE_ZMQMSG, msg_id);
+}
static void serverpartfn(void *arg, void *zmqsock, zmq_msg_t *msg,
- unsigned partnum)
+ unsigned partnum)
{
+ static int num = 0;
int more = zmq_msg_more(msg);
char *in = zmq_msg_data(msg);
size_t i;
zmq_msg_t reply;
char *out;
+ /* Id */
+ if (partnum == 0) {
+ send_id_and_delim(zmqsock, msg);
+ return;
+ }
+ /* Delim */
+ if (partnum == 1)
+ return;
+
+
printf("server recv part %u (more: %d): %s\n", partnum, more, in);
fflush(stdout);
- /* REQ-REP doesn't allow sending a reply here */
- if (more)
- return;
out = XMALLOC(MTYPE_TESTBUF, strlen(in) + 1);
for (i = 0; i < strlen(in); i++)
zmq_msg_init_data(&reply, out, strlen(out) + 1, msg_buf_free, NULL);
zmq_msg_send(&reply, zmqsock, ZMQ_SNDMORE);
+ if (more)
+ return;
+
out = XMALLOC(MTYPE_TESTBUF, 32);
snprintf(out, 32, "msg# was %u", partnum);
zmq_msg_init_data(&reply, out, strlen(out) + 1, msg_buf_free, NULL);
zmq_msg_send(&reply, zmqsock, 0);
+
+ zmq_msg_close(&reply);
+
+ if (++num < 7)
+ return;
+
+ /* write callback test */
+ char buf[32];
+ zmq_msg_t *msg_id = XMALLOC(MTYPE_ZMQMSG, sizeof(zmq_msg_t));
+ recv_id_and_delim(zmqsock, msg_id);
+ zmq_recv(zmqsock, buf, sizeof(buf), 0);
+ printf("server recv: %s\n", buf);
+ fflush(stdout);
+
+ frrzmq_thread_add_write_msg(master, serverwritefn, NULL, msg_id,
+ zmqsock, &cb);
}
static void serverfn(void *arg, void *zmqsock)
{
static int num = 0;
+ zmq_msg_t msg_id;
char buf[32];
size_t i;
+
+ recv_id_and_delim(zmqsock, &msg_id);
zmq_recv(zmqsock, buf, sizeof(buf), 0);
printf("server recv: %s\n", buf);
fflush(stdout);
for (i = 0; i < strlen(buf); i++)
buf[i] = toupper(buf[i]);
+ send_id_and_delim(zmqsock, &msg_id);
+ zmq_msg_close(&msg_id);
zmq_send(zmqsock, buf, strlen(buf) + 1, 0);
if (++num < 4)
return;
/* change to multipart callback */
- frrzmq_thread_cancel(cb);
+ frrzmq_thread_cancel(&cb, &cb->read);
+ frrzmq_thread_cancel(&cb, &cb->write);
- cb = frrzmq_thread_add_read_part(master, serverpartfn, NULL, zmqsock);
+ frrzmq_thread_add_read_part(master, serverpartfn, NULL, NULL, zmqsock,
+ &cb);
}
static void sigchld(void)
{
printf("child exited.\n");
- frrzmq_thread_cancel(cb);
+ frrzmq_thread_cancel(&cb, &cb->read);
+ frrzmq_thread_cancel(&cb, &cb->write);
}
static struct quagga_signal_t sigs[] = {
signal_init(master, array_size(sigs), sigs);
frrzmq_init();
- zmqsock = zmq_socket(frrzmq_context, ZMQ_REP);
+ zmqsock = zmq_socket(frrzmq_context, ZMQ_ROUTER);
if (zmq_bind(zmqsock, "tcp://*:17171")) {
perror("zmq_bind");
exit(1);
}
- cb = frrzmq_thread_add_read_msg(master, serverfn, NULL, zmqsock);
+ frrzmq_thread_add_read_msg(master, serverfn, NULL, NULL, zmqsock, &cb);
write(syncfd, &dummy, sizeof(dummy));
while (thread_fetch(master, &t))
server recv: msg #3 def
client recv: MSG #3 DEF
client send: msg #4 efg
-server recv part 0 (more: 0): msg #4 efg
+server recv part 2 (more: 0): msg #4 efg
client recv: MSG #4 EFG
+client recv: msg# was 2
client send: msg #5 fgh
-client recv: msg# was 0
+server recv part 2 (more: 0): msg #5 fgh
+client recv: MSG #5 FGH
+client recv: msg# was 2
client send: msg #6 ghi
-server recv part 0 (more: 0): msg #6 ghi
+server recv part 2 (more: 0): msg #6 ghi
client recv: MSG #6 GHI
+client recv: msg# was 2
client send: msg #7 hij
-client recv: msg# was 0
+server recv part 2 (more: 0): msg #7 hij
+client recv: MSG #7 HIJ
+client recv: msg# was 2
---
client send: part 1/2
client send: part 2/2
-server recv part 0 (more: 1): part 1/2
-server recv part 1 (more: 0): part 2/2
+server recv part 2 (more: 1): part 1/2
+server recv part 3 (more: 0): part 2/2
+client recv (more: 1): PART 1/2
client recv (more: 1): PART 2/2
-client recv (more: 0): msg# was 1
+client recv (more: 0): msg# was 3
---
client send: part 1/3
client send: part 2/3
client send: part 3/3
-server recv part 0 (more: 1): part 1/3
-server recv part 1 (more: 1): part 2/3
-server recv part 2 (more: 0): part 3/3
+server recv part 2 (more: 1): part 1/3
+server recv part 3 (more: 1): part 2/3
+server recv part 4 (more: 0): part 3/3
+client recv (more: 1): PART 1/3
+client recv (more: 1): PART 2/3
client recv (more: 1): PART 3/3
-client recv (more: 0): msg# was 2
+client recv (more: 0): msg# was 4
---
client send: part 1/4
client send: part 2/4
client send: part 3/4
client send: part 4/4
-server recv part 0 (more: 1): part 1/4
-server recv part 1 (more: 1): part 2/4
-server recv part 2 (more: 1): part 3/4
-server recv part 3 (more: 0): part 4/4
+server recv part 2 (more: 1): part 1/4
+server recv part 3 (more: 1): part 2/4
+server recv part 4 (more: 1): part 3/4
+server recv part 5 (more: 0): part 4/4
+client recv (more: 1): PART 1/4
+client recv (more: 1): PART 2/4
+client recv (more: 1): PART 3/4
client recv (more: 1): PART 4/4
-client recv (more: 0): msg# was 3
+client recv (more: 0): msg# was 5
+---
+client send: Done receiving
+server recv: Done receiving
+server send: TEST WRITE CALLBACK
+client recv: TEST WRITE CALLBACK
child exited.
# The list of daemons to watch is automatically generated by the init script.
watchfrr_enable=yes
-watchfrr_options=(-d -r /usr/sbin/servicebBfrrbBrestartbB%s -s /usr/sbin/servicebBfrrbBstartbB%s -k /usr/sbin/servicebBfrrbBstopbB%s -b bB -t 30)
+watchfrr_options=(-d -r /usr/sbin/servicebBfrrbBrestartbB%s -s /usr/sbin/servicebBfrrbBstartbB%s -k /usr/sbin/servicebBfrrbBstopbB%s -b bB)
# If valgrind_enable is 'yes' the frr daemons will be started via valgrind.
# The use case for doing so is tracking down memory leaks, etc in frr.
#define FUZZY(X) ((X)+JITTER((X)/20))
#define DEFAULT_PERIOD 5
-#define DEFAULT_TIMEOUT 10
+#define DEFAULT_TIMEOUT 90
#define DEFAULT_RESTART_TIMEOUT 20
#define DEFAULT_LOGLEVEL LOG_INFO
#define DEFAULT_MIN_RESTART 60
FILE *fp;
fp = fopen(DAEMON_VTY_DIR "/watchfrr.started", "w");
- fclose(fp);
+ if (fp)
+ fclose(fp);
#if defined HAVE_SYSTEMD
zlog_notice(
"Watchfrr: Notifying Systemd we are up and running");
}
rib_add(afi, SAFI_UNICAST, ifp->vrf_id, ZEBRA_ROUTE_CONNECT, 0, 0,
- &p, NULL, &nh, RT_TABLE_MAIN, ifp->metric, 0, 0);
+ &p, NULL, &nh, RT_TABLE_MAIN, ifp->metric, 0, 0, 0);
rib_add(afi, SAFI_MULTICAST, ifp->vrf_id, ZEBRA_ROUTE_CONNECT, 0, 0,
- &p, NULL, &nh, RT_TABLE_MAIN, ifp->metric, 0, 0);
+ &p, NULL, &nh, RT_TABLE_MAIN, ifp->metric, 0, 0, 0);
if (IS_ZEBRA_DEBUG_RIB_DETAILED) {
char buf[PREFIX_STRLEN];
return netlink_address(RTM_DELADDR, AF_INET, ifp, ifc);
}
+int kernel_address_add_ipv6 (struct interface *ifp, struct connected *ifc)
+{
+ return netlink_address (RTM_NEWADDR, AF_INET6, ifp, ifc);
+}
+
+int kernel_address_delete_ipv6 (struct interface *ifp, struct connected *ifc)
+{
+ return netlink_address (RTM_DELADDR, AF_INET6, ifp, ifc);
+}
+
int netlink_interface_addr(struct sockaddr_nl *snl, struct nlmsghdr *h,
ns_id_t ns_id, int startup)
{
struct prefix cp;
struct route_node *rn;
struct zebra_if *zebra_if;
+ struct listnode *node;
+ struct listnode *last = NULL;
zebra_if = ifp->info;
- if (ifp->connected) {
- struct listnode *node;
- struct listnode *last = NULL;
+ if (!ifp->connected)
+ return;
- while ((node = (last ? last->next
- : listhead(ifp->connected)))) {
- ifc = listgetdata(node);
+ while ((node = (last ? last->next
+ : listhead(ifp->connected)))) {
+ ifc = listgetdata(node);
- cp = *CONNECTED_PREFIX(ifc);
- apply_mask(&cp);
+ cp = *CONNECTED_PREFIX(ifc);
+ apply_mask(&cp);
- if (cp.family == AF_INET
- && (rn = route_node_lookup(zebra_if->ipv4_subnets,
- &cp))) {
- struct listnode *anode;
- struct listnode *next;
- struct listnode *first;
- struct list *addr_list;
+ if (cp.family == AF_INET
+ && (rn = route_node_lookup(zebra_if->ipv4_subnets,
+ &cp))) {
+ struct listnode *anode;
+ struct listnode *next;
+ struct listnode *first;
+ struct list *addr_list;
- route_unlock_node(rn);
- addr_list = (struct list *)rn->info;
+ route_unlock_node(rn);
+ addr_list = (struct list *)rn->info;
- /* Remove addresses, secondaries first. */
- first = listhead(addr_list);
+ /* Remove addresses, secondaries first. */
+ first = listhead(addr_list);
+ if (first)
for (anode = first->next; anode || first;
anode = next) {
if (!anode) {
last = node;
}
- /* Free chain list and respective route node. */
- list_delete_and_null(&addr_list);
- rn->info = NULL;
- route_unlock_node(rn);
- } else if (cp.family == AF_INET6) {
- connected_down(ifp, ifc);
+ /* Free chain list and respective route node. */
+ list_delete_and_null(&addr_list);
+ rn->info = NULL;
+ route_unlock_node(rn);
+ } else if (cp.family == AF_INET6) {
+ connected_down(ifp, ifc);
- zebra_interface_address_delete_update(ifp, ifc);
+ zebra_interface_address_delete_update(ifp, ifc);
- UNSET_FLAG(ifc->conf, ZEBRA_IFC_REAL);
- UNSET_FLAG(ifc->conf, ZEBRA_IFC_QUEUED);
+ UNSET_FLAG(ifc->conf, ZEBRA_IFC_REAL);
+ UNSET_FLAG(ifc->conf, ZEBRA_IFC_QUEUED);
- if (CHECK_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED))
- last = node;
- else {
- listnode_delete(ifp->connected, ifc);
- connected_free(ifc);
- }
- } else {
+ if (CHECK_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED))
last = node;
+ else {
+ listnode_delete(ifp->connected, ifc);
+ connected_free(ifc);
}
+ } else {
+ last = node;
}
}
}
#define RTADV_PREF_MEDIUM 0x0 /* Per RFC4191. */
u_char inFastRexmit; /* True if we're rexmits faster than usual */
- u_char configured; /* Has operator configured RA? */
+
+ /* Track if RA was configured by BGP or by the Operator or both */
+ u_char ra_configured; /* Was RA configured? */
+#define BGP_RA_CONFIGURED (1<<0) /* BGP configured RA? */
+#define VTY_RA_CONFIGURED (1<<1) /* Operator configured RA? */
+#define VTY_RA_INTERVAL_CONFIGURED (1<<2) /* Operator configured RA interval */
int
NumFastReXmitsRemain; /* Loaded first with number of fast
rexmits to do */
#define IS_ZEBRA_IF_VRF_SLAVE(ifp) \
(((struct zebra_if *)(ifp->info))->zif_slave_type == ZEBRA_IF_SLAVE_VRF)
+extern void zebra_if_init(void);
+
extern struct interface *if_lookup_by_index_per_ns(struct zebra_ns *,
u_int32_t);
extern struct interface *if_lookup_by_name_per_ns(struct zebra_ns *,
return 0;
}
+#ifndef HAVE_NETLINK
static int if_ioctl_ipv6(u_long request, caddr_t buffer)
{
int sock;
}
return 0;
}
+#endif /* ! HAVE_NETLINK */
/*
* get interface metric
int ifr6_ifindex;
};
#endif /* _LINUX_IN6_H */
-
/* Interface's address add/delete functions. */
int if_prefix_add_ipv6(struct interface *ifp, struct connected *ifc)
{
- int ret;
- struct prefix_ipv6 *p;
- struct in6_ifreq ifreq;
-
- p = (struct prefix_ipv6 *)ifc->address;
-
- memset(&ifreq, 0, sizeof(struct in6_ifreq));
-
- memcpy(&ifreq.ifr6_addr, &p->prefix, sizeof(struct in6_addr));
- ifreq.ifr6_ifindex = ifp->ifindex;
- ifreq.ifr6_prefixlen = p->prefixlen;
-
- ret = if_ioctl_ipv6(SIOCSIFADDR, (caddr_t)&ifreq);
-
- return ret;
+#ifdef HAVE_NETLINK
+ return kernel_address_add_ipv6 (ifp, ifc);
+#endif /* HAVE_NETLINK */
}
int if_prefix_delete_ipv6(struct interface *ifp, struct connected *ifc)
{
- int ret;
- struct prefix_ipv6 *p;
- struct in6_ifreq ifreq;
-
- p = (struct prefix_ipv6 *)ifc->address;
-
- memset(&ifreq, 0, sizeof(struct in6_ifreq));
-
- memcpy(&ifreq.ifr6_addr, &p->prefix, sizeof(struct in6_addr));
- ifreq.ifr6_ifindex = ifp->ifindex;
- ifreq.ifr6_prefixlen = p->prefixlen;
-
- ret = if_ioctl_ipv6(SIOCDIFADDR, (caddr_t)&ifreq);
-
- return ret;
+#ifdef HAVE_NETLINK
+ return kernel_address_delete_ipv6 (ifp, ifc);
+#endif /* HAVE_NETLINK */
}
#else /* LINUX_IPV6 */
#ifdef HAVE_STRUCT_IN6_ALIASREQ
int ipforward(void)
{
+ int ret = 0;
FILE *fp;
int ipforwarding = 0;
char buf[10];
1 => ip forwarding enabled
2 => ip forwarding off. */
if (fgets(buf, 6, fp))
- sscanf(buf, "Ip: %d", &ipforwarding);
+ ret = sscanf(buf, "Ip: %d", &ipforwarding);
fclose(fp);
- if (ipforwarding == 1)
+ if (ret == 1 && ipforwarding == 1)
return 1;
return 0;
int ipforward_ipv6(void)
{
+ int ret = 0;
FILE *fp;
char buf[5];
int ipforwarding = 0;
return -1;
if (fgets(buf, 2, fp))
- sscanf(buf, "%d", &ipforwarding);
+ ret = sscanf(buf, "%d", &ipforwarding);
fclose(fp);
+
+ if (ret != 1)
+ return 0;
+
return ipforwarding;
}
#include "zebra/zserv.h"
#include "zebra/zebra_ns.h"
#include "zebra/zebra_vrf.h"
+#include "zebra/rt.h"
#include "zebra/debug.h"
#include "zebra/kernel_netlink.h"
#include "zebra/rt_netlink.h"
|| rtm->rtm_type == RTM_CHANGE)
rib_add(AFI_IP, SAFI_UNICAST, VRF_DEFAULT,
ZEBRA_ROUTE_KERNEL, 0, zebra_flags, &p, NULL,
- &nh, 0, 0, 0, 0);
+ &nh, 0, 0, 0, 0, 0);
else
rib_delete(AFI_IP, SAFI_UNICAST, VRF_DEFAULT,
ZEBRA_ROUTE_KERNEL, 0, zebra_flags, &p, NULL,
|| rtm->rtm_type == RTM_CHANGE)
rib_add(AFI_IP6, SAFI_UNICAST, VRF_DEFAULT,
ZEBRA_ROUTE_KERNEL, 0, zebra_flags, &p, NULL,
- &nh, 0, 0, 0, 0);
+ &nh, 0, 0, 0, 0, 0);
else
rib_delete(AFI_IP6, SAFI_UNICAST, VRF_DEFAULT,
ZEBRA_ROUTE_KERNEL, 0, zebra_flags, &p, NULL,
zebrad.master = frr_init();
/* Zebra related initialize. */
- zebra_init();
+ zserv_init();
rib_init();
zebra_if_init();
zebra_debug_init();
u_short instance, int flags, struct prefix *p,
struct prefix_ipv6 *src_p, const struct nexthop *nh,
u_int32_t table_id, u_int32_t metric, u_int32_t mtu,
- uint8_t distance);
+ uint8_t distance, route_tag_t tag);
extern int rib_add_multipath(afi_t afi, safi_t safi, struct prefix *,
struct prefix_ipv6 *src_p, struct route_entry *);
DECLARE_HOOK(rib_update, (struct route_node * rn, const char *reason),
(rn, reason))
+
+extern void zebra_vty_init(void);
+extern pid_t pid;
+
#endif /*_ZEBRA_RIB_H */
extern int kernel_address_add_ipv4(struct interface *, struct connected *);
extern int kernel_address_delete_ipv4(struct interface *, struct connected *);
+extern int kernel_address_add_ipv6 (struct interface *, struct connected *);
+extern int kernel_address_delete_ipv6 (struct interface *, struct connected *);
extern int kernel_neigh_update(int, int, uint32_t, char *, int);
extern int kernel_interface_set_master(struct interface *master,
struct interface *slave);
struct ethaddr *mac);
extern int kernel_del_neigh(struct interface *ifp, struct ipaddr *ip);
+/*
+ * Southbound Initialization routines to get initial starting
+ * state.
+ */
+extern void interface_list(struct zebra_ns *zns);
+extern void kernel_init(struct zebra_ns *zns);
+extern void kernel_terminate(struct zebra_ns *zns);
+extern void macfdb_read(struct zebra_ns *zns);
+extern void macfdb_read_for_bridge(struct zebra_ns *zns, struct interface *ifp,
+ struct interface *br_if);
+extern void neigh_read(struct zebra_ns *zns);
+extern void neigh_read_for_vlan(struct zebra_ns *zns, struct interface *ifp);
+extern void route_read(struct zebra_ns *zns);
+
#endif /* _ZEBRA_RT_H */
int metric = 0;
u_int32_t mtu = 0;
uint8_t distance = 0;
+ route_tag_t tag = 0;
void *dest = NULL;
void *gate = NULL;
if (tb[RTA_PRIORITY])
metric = *(int *)RTA_DATA(tb[RTA_PRIORITY]);
+#if defined(SUPPORT_REALMS)
+ if (tb[RTA_FLOW])
+ tag = *(uint32_t *)RTA_DATA(tb[RTA_FLOW]);
+#endif
+
if (tb[RTA_METRICS]) {
struct rtattr *mxrta[RTAX_MAX + 1];
memcpy(&nh.gate, gate, sz);
rib_add(afi, SAFI_UNICAST, vrf_id, proto,
- 0, flags, &p, NULL, &nh, table, metric, mtu, distance);
+ 0, flags, &p, NULL, &nh, table, metric,
+ mtu, distance, tag);
} else {
/* This is a multipath route */
re->table = table;
re->nexthop_num = 0;
re->uptime = time(NULL);
+ re->tag = tag;
for (;;) {
if (len < (int)sizeof(*rtnh)
* by the routing protocol and for communicating with protocol peers.
*/
addattr32(&req.n, sizeof req, RTA_PRIORITY, NL_DEFAULT_ROUTE_METRIC);
-
+#if defined(SUPPORT_REALMS)
+ if (re->tag > 0 && re->tag <= 255)
+ addattr32(&req.n, sizeof req, RTA_FLOW, re->tag);
+#endif
/* Table corresponding to this route. */
if (re->table < 256)
req.r.rtm_table = re->table;
zif = ifp->info;
if (enable) {
+ SET_FLAG(zif->rtadv.ra_configured, BGP_RA_CONFIGURED);
ipv6_nd_suppress_ra_set(ifp, RA_ENABLE);
if (ra_interval
- && (ra_interval * 1000) < zif->rtadv.MaxRtrAdvInterval)
+ && (ra_interval * 1000) < zif->rtadv.MaxRtrAdvInterval
+ && !CHECK_FLAG(zif->rtadv.ra_configured,
+ VTY_RA_INTERVAL_CONFIGURED))
zif->rtadv.MaxRtrAdvInterval = ra_interval * 1000;
} else {
- if (!zif->rtadv.configured) {
+ UNSET_FLAG(zif->rtadv.ra_configured, BGP_RA_CONFIGURED);
+ if (!CHECK_FLAG(zif->rtadv.ra_configured,
+ VTY_RA_INTERVAL_CONFIGURED))
zif->rtadv.MaxRtrAdvInterval =
RTADV_MAX_RTR_ADV_INTERVAL;
+ if (!CHECK_FLAG(zif->rtadv.ra_configured, VTY_RA_CONFIGURED))
ipv6_nd_suppress_ra_set(ifp, RA_SUPPRESS);
- }
}
stream_failure:
return;
return CMD_WARNING_CONFIG_FAILED;
}
- ipv6_nd_suppress_ra_set(ifp, RA_SUPPRESS);
- zif->rtadv.configured = 0;
+ if (!CHECK_FLAG(zif->rtadv.ra_configured, BGP_RA_CONFIGURED))
+ ipv6_nd_suppress_ra_set(ifp, RA_SUPPRESS);
+
+ UNSET_FLAG(zif->rtadv.ra_configured, VTY_RA_CONFIGURED);
return CMD_SUCCESS;
}
}
ipv6_nd_suppress_ra_set(ifp, RA_ENABLE);
- zif->rtadv.configured = 1;
+ SET_FLAG(zif->rtadv.ra_configured, VTY_RA_CONFIGURED);
return CMD_SUCCESS;
}
if (interval % 1000)
zns->rtadv.adv_msec_if_count++;
+ SET_FLAG(zif->rtadv.ra_configured, VTY_RA_INTERVAL_CONFIGURED);
zif->rtadv.MaxRtrAdvInterval = interval;
zif->rtadv.MinRtrAdvInterval = 0.33 * interval;
zif->rtadv.AdvIntervalTimer = 0;
/* convert to milliseconds */
interval = interval * 1000;
+ SET_FLAG(zif->rtadv.ra_configured, VTY_RA_INTERVAL_CONFIGURED);
zif->rtadv.MaxRtrAdvInterval = interval;
zif->rtadv.MinRtrAdvInterval = 0.33 * interval;
zif->rtadv.AdvIntervalTimer = 0;
if (zif->rtadv.MaxRtrAdvInterval % 1000)
zns->rtadv.adv_msec_if_count--;
- zif->rtadv.MaxRtrAdvInterval = RTADV_MAX_RTR_ADV_INTERVAL;
- zif->rtadv.MinRtrAdvInterval = RTADV_MIN_RTR_ADV_INTERVAL;
+ UNSET_FLAG(zif->rtadv.ra_configured, VTY_RA_INTERVAL_CONFIGURED);
+
+ if (CHECK_FLAG(zif->rtadv.ra_configured, BGP_RA_CONFIGURED))
+ zif->rtadv.MaxRtrAdvInterval = 10000;
+ else
+ zif->rtadv.MaxRtrAdvInterval = RTADV_MAX_RTR_ADV_INTERVAL;
+
zif->rtadv.AdvIntervalTimer = zif->rtadv.MaxRtrAdvInterval;
+ zif->rtadv.MinRtrAdvInterval = RTADV_MIN_RTR_ADV_INTERVAL;
return CMD_SUCCESS;
}
if (!(if_is_loopback(ifp)
|| CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_VRF_LOOPBACK))) {
- if (zif->rtadv.AdvSendAdvertisements)
+ if (zif->rtadv.AdvSendAdvertisements
+ && CHECK_FLAG(zif->rtadv.ra_configured, VTY_RA_CONFIGURED))
vty_out(vty, " no ipv6 nd suppress-ra\n");
}
interval = zif->rtadv.MaxRtrAdvInterval;
- if (interval % 1000)
- vty_out(vty, " ipv6 nd ra-interval msec %d\n", interval);
- else if (interval != RTADV_MAX_RTR_ADV_INTERVAL)
- vty_out(vty, " ipv6 nd ra-interval %d\n", interval / 1000);
+ if (CHECK_FLAG(zif->rtadv.ra_configured, VTY_RA_INTERVAL_CONFIGURED)) {
+ if (interval % 1000)
+ vty_out(vty, " ipv6 nd ra-interval msec %d\n",
+ interval);
+ else if (interval != RTADV_MAX_RTR_ADV_INTERVAL)
+ vty_out(vty, " ipv6 nd ra-interval %d\n",
+ interval / 1000);
+ }
if (zif->rtadv.AdvIntervalOption)
vty_out(vty, " ipv6 nd adv-interval-option\n");
#include "vty.h"
#include "zebra/rib.h"
-#include "zebra/zserv.h"
+#include "zebra/rt.h"
/* Thank you, Solaris, for polluting application symbol namespace. */
#undef hook_register
nh.gate.ipv4.s_addr = routeEntry->ipRouteNextHop;
rib_add(AFI_IP, SAFI_UNICAST, VRF_DEFAULT, ZEBRA_ROUTE_KERNEL, 0,
- zebra_flags, &prefix, NULL, &nh, 0, 0, 0, 0);
+ zebra_flags, &prefix, NULL, &nh, 0, 0, 0, 0, 0);
}
void route_read(struct zebra_ns *zns)
#ifdef GNU_LINUX
#include "vty.h"
-#include "zebra/zserv.h"
+#include "zebra/rt.h"
#include "zebra/rt_netlink.h"
void route_read(struct zebra_ns *zns)
#include "log.h"
#include "vrf.h"
-#include "zebra/zserv.h"
#include "zebra/rt.h"
#include "zebra/kernel_socket.h"
#include "zebra_ns.h"
#include "zebra_vrf.h"
#include "zebra_memory.h"
+#include "rt.h"
DEFINE_MTYPE(ZEBRA, ZEBRA_NS, "Zebra Name Space")
zebra_ptm_send_message(ptm_cb.out_data, data_len);
stream_failure:
+ ptm_lib_cleanup_msg(ptm_hdl, out_ctxt);
return 0;
}
zebra_ptm_send_message(ptm_cb.out_data, data_len);
stream_failure:
+ ptm_lib_cleanup_msg(ptm_hdl, out_ctxt);
return 0;
}
int rib_add(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type, u_short instance,
int flags, struct prefix *p, struct prefix_ipv6 *src_p,
const struct nexthop *nh, u_int32_t table_id, u_int32_t metric,
- u_int32_t mtu, uint8_t distance)
+ u_int32_t mtu, uint8_t distance, route_tag_t tag)
{
struct route_entry *re;
struct nexthop *nexthop;
re->vrf_id = vrf_id;
re->nexthop_num = 0;
re->uptime = time(NULL);
+ re->tag = tag;
/* Add nexthop. */
nexthop = nexthop_new();
#ifndef __ZEBRA_ROUTEMAP_H__
#define __ZEBRA_ROUTEMAP_H__
+extern void zebra_route_map_init(void);
extern void zebra_routemap_config_write_protocol(struct vty *vty);
extern char *zebra_get_import_table_route_map(afi_t afi, uint32_t table);
extern void zebra_add_import_table_route_map(afi_t afi, const char *rmap_name,
#include "zebra/zebra_vty_clippy.c"
#endif
#include "zebra/zserv.h"
+#include "zebra/router-id.h"
+#include "zebra/ipforward.h"
extern int allow_delete;
vty_out(vty, "\"");
vty_out(vty, ", distance %u, metric %u", re->distance,
re->metric);
- if (re->tag)
+ if (re->tag) {
vty_out(vty, ", tag %u", re->tag);
+#if defined(SUPPORT_REALMS)
+ if (re->tag > 0 && re->tag <= 255)
+ vty_out(vty, "(realm)");
+#endif
+ }
if (re->mtu)
vty_out(vty, ", mtu %u", re->mtu);
if (re->vrf_id != VRF_DEFAULT) {
return 1;
}
+#ifdef HAVE_NETLINK
+/* Display default rtm_table for all clients. */
+DEFUN (show_table,
+ show_table_cmd,
+ "show table",
+ SHOW_STR
+ "default routing table to use for all clients\n")
+{
+ vty_out(vty, "table %d\n", zebrad.rtm_table_default);
+ return CMD_SUCCESS;
+}
+
+DEFUN (config_table,
+ config_table_cmd,
+ "table TABLENO",
+ "Configure target kernel routing table\n"
+ "TABLE integer\n")
+{
+ zebrad.rtm_table_default = strtol(argv[1]->arg, (char **)0, 10);
+ return CMD_SUCCESS;
+}
+
+DEFUN (no_config_table,
+ no_config_table_cmd,
+ "no table [TABLENO]",
+ NO_STR
+ "Configure target kernel routing table\n"
+ "TABLE integer\n")
+{
+ zebrad.rtm_table_default = 0;
+ return CMD_SUCCESS;
+}
+#endif
+
+DEFUN (show_zebra,
+ show_zebra_cmd,
+ "show zebra",
+ SHOW_STR
+ ZEBRA_STR)
+{
+ struct vrf *vrf;
+
+ vty_out(vty,
+ " Route Route Neighbor LSP LSP\n");
+ vty_out(vty,
+ "VRF Installs Removals Updates Installs Removals\n");
+
+ RB_FOREACH(vrf, vrf_name_head, &vrfs_by_name) {
+ struct zebra_vrf *zvrf = vrf->info;
+
+ vty_out(vty, "%-25s %10" PRIu64 " %10" PRIu64 " %10" PRIu64
+ " %10" PRIu64 " %10" PRIu64 "\n",
+ vrf->name, zvrf->installs, zvrf->removals,
+ zvrf->neigh_updates, zvrf->lsp_installs,
+ zvrf->lsp_removals);
+ }
+
+ return CMD_SUCCESS;
+}
+
+DEFUN (ip_forwarding,
+ ip_forwarding_cmd,
+ "ip forwarding",
+ IP_STR
+ "Turn on IP forwarding\n")
+{
+ int ret;
+
+ ret = ipforward();
+ if (ret == 0)
+ ret = ipforward_on();
+
+ if (ret == 0) {
+ vty_out(vty, "Can't turn on IP forwarding\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+
+ return CMD_SUCCESS;
+}
+
+DEFUN (no_ip_forwarding,
+ no_ip_forwarding_cmd,
+ "no ip forwarding",
+ NO_STR
+ IP_STR
+ "Turn off IP forwarding\n")
+{
+ int ret;
+
+ ret = ipforward();
+ if (ret != 0)
+ ret = ipforward_off();
+
+ if (ret != 0) {
+ vty_out(vty, "Can't turn off IP forwarding\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+
+ return CMD_SUCCESS;
+}
+
+/* Only display ip forwarding is enabled or not. */
+DEFUN (show_ip_forwarding,
+ show_ip_forwarding_cmd,
+ "show ip forwarding",
+ SHOW_STR
+ IP_STR
+ "IP forwarding status\n")
+{
+ int ret;
+
+ ret = ipforward();
+
+ if (ret == 0)
+ vty_out(vty, "IP forwarding is off\n");
+ else
+ vty_out(vty, "IP forwarding is on\n");
+ return CMD_SUCCESS;
+}
+
+/* Only display ipv6 forwarding is enabled or not. */
+DEFUN (show_ipv6_forwarding,
+ show_ipv6_forwarding_cmd,
+ "show ipv6 forwarding",
+ SHOW_STR
+ "IPv6 information\n"
+ "Forwarding status\n")
+{
+ int ret;
+
+ ret = ipforward_ipv6();
+
+ switch (ret) {
+ case -1:
+ vty_out(vty, "ipv6 forwarding is unknown\n");
+ break;
+ case 0:
+ vty_out(vty, "ipv6 forwarding is %s\n", "off");
+ break;
+ case 1:
+ vty_out(vty, "ipv6 forwarding is %s\n", "on");
+ break;
+ default:
+ vty_out(vty, "ipv6 forwarding is %s\n", "off");
+ break;
+ }
+ return CMD_SUCCESS;
+}
+
+DEFUN (ipv6_forwarding,
+ ipv6_forwarding_cmd,
+ "ipv6 forwarding",
+ IPV6_STR
+ "Turn on IPv6 forwarding\n")
+{
+ int ret;
+
+ ret = ipforward_ipv6();
+ if (ret == 0)
+ ret = ipforward_ipv6_on();
+
+ if (ret == 0) {
+ vty_out(vty, "Can't turn on IPv6 forwarding\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+
+ return CMD_SUCCESS;
+}
+
+DEFUN (no_ipv6_forwarding,
+ no_ipv6_forwarding_cmd,
+ "no ipv6 forwarding",
+ NO_STR
+ IPV6_STR
+ "Turn off IPv6 forwarding\n")
+{
+ int ret;
+
+ ret = ipforward_ipv6();
+ if (ret != 0)
+ ret = ipforward_ipv6_off();
+
+ if (ret != 0) {
+ vty_out(vty, "Can't turn off IPv6 forwarding\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+
+ return CMD_SUCCESS;
+}
+
+/* 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);
+ return 0;
+}
+
+/* IPForwarding configuration write function. */
+static int config_write_forwarding(struct vty *vty)
+{
+ /* FIXME: Find better place for that. */
+ router_id_write(vty);
+
+ if (!ipforward())
+ vty_out(vty, "no ip forwarding\n");
+ if (!ipforward_ipv6())
+ vty_out(vty, "no ipv6 forwarding\n");
+ vty_out(vty, "!\n");
+ return 0;
+}
+
/* IP node for static routes. */
static struct cmd_node ip_node = {IP_NODE, "", 1};
static struct cmd_node protocol_node = {PROTOCOL_NODE, "", 1};
+/* table node for routing tables. */
+static struct cmd_node table_node = {TABLE_NODE,
+ "", /* This node has no interface. */
+ 1};
+static struct cmd_node forwarding_node = {FORWARDING_NODE,
+ "", /* This node has no interface. */
+ 1};
/* Route VTY. */
void zebra_vty_init(void)
{
+ /* Install configuration write function. */
+ install_node(&table_node, config_write_table);
+ install_node(&forwarding_node, config_write_forwarding);
+
+ install_element(VIEW_NODE, &show_ip_forwarding_cmd);
+ install_element(CONFIG_NODE, &ip_forwarding_cmd);
+ install_element(CONFIG_NODE, &no_ip_forwarding_cmd);
+ install_element(ENABLE_NODE, &show_zebra_cmd);
+
+#ifdef HAVE_NETLINK
+ install_element(VIEW_NODE, &show_table_cmd);
+ install_element(CONFIG_NODE, &config_table_cmd);
+ install_element(CONFIG_NODE, &no_config_table_cmd);
+#endif /* HAVE_NETLINK */
+
+ install_element(VIEW_NODE, &show_ipv6_forwarding_cmd);
+ install_element(CONFIG_NODE, &ipv6_forwarding_cmd);
+ install_element(CONFIG_NODE, &no_ipv6_forwarding_cmd);
+
+ /* Route-map */
+ zebra_route_map_init();
+
install_node(&ip_node, zebra_ip_config);
install_node(&protocol_node, config_write_protocol);
#include "zebra/router-id.h"
#include "zebra/redistribute.h"
#include "zebra/debug.h"
-#include "zebra/ipforward.h"
#include "zebra/zebra_rnh.h"
#include "zebra/rt_netlink.h"
#include "zebra/interface.h"
return NULL;
}
-#ifdef HAVE_NETLINK
-/* Display default rtm_table for all clients. */
-DEFUN (show_table,
- show_table_cmd,
- "show table",
- SHOW_STR
- "default routing table to use for all clients\n")
-{
- vty_out(vty, "table %d\n", zebrad.rtm_table_default);
- return CMD_SUCCESS;
-}
-
-DEFUN (config_table,
- config_table_cmd,
- "table TABLENO",
- "Configure target kernel routing table\n"
- "TABLE integer\n")
-{
- zebrad.rtm_table_default = strtol(argv[1]->arg, (char **)0, 10);
- return CMD_SUCCESS;
-}
-
-DEFUN (no_config_table,
- no_config_table_cmd,
- "no table [TABLENO]",
- NO_STR
- "Configure target kernel routing table\n"
- "TABLE integer\n")
-{
- zebrad.rtm_table_default = 0;
- return CMD_SUCCESS;
-}
-#endif
-
-DEFUN (ip_forwarding,
- ip_forwarding_cmd,
- "ip forwarding",
- IP_STR
- "Turn on IP forwarding\n")
-{
- int ret;
-
- ret = ipforward();
- if (ret == 0)
- ret = ipforward_on();
-
- if (ret == 0) {
- vty_out(vty, "Can't turn on IP forwarding\n");
- return CMD_WARNING_CONFIG_FAILED;
- }
-
- return CMD_SUCCESS;
-}
-
-DEFUN (no_ip_forwarding,
- no_ip_forwarding_cmd,
- "no ip forwarding",
- NO_STR
- IP_STR
- "Turn off IP forwarding\n")
-{
- int ret;
-
- ret = ipforward();
- if (ret != 0)
- ret = ipforward_off();
-
- if (ret != 0) {
- vty_out(vty, "Can't turn off IP forwarding\n");
- return CMD_WARNING_CONFIG_FAILED;
- }
-
- return CMD_SUCCESS;
-}
-
-DEFUN (show_zebra,
- show_zebra_cmd,
- "show zebra",
- SHOW_STR
- ZEBRA_STR)
-{
- struct vrf *vrf;
-
- vty_out(vty,
- " Route Route Neighbor LSP LSP\n");
- vty_out(vty,
- "VRF Installs Removals Updates Installs Removals\n");
- RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
- struct zebra_vrf *zvrf = vrf->info;
- vty_out(vty, "%-25s %10" PRIu64 " %10" PRIu64 " %10" PRIu64
- " %10" PRIu64 " %10" PRIu64 "\n",
- vrf->name, zvrf->installs, zvrf->removals,
- zvrf->neigh_updates, zvrf->lsp_installs,
- zvrf->lsp_removals);
- }
-
- return CMD_SUCCESS;
-}
-
/* This command is for debugging purpose. */
DEFUN (show_zebra_client,
show_zebra_client_cmd,
return CMD_SUCCESS;
}
-/* 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);
- return 0;
-}
-
-/* table node for routing tables. */
-static struct cmd_node table_node = {TABLE_NODE,
- "", /* This node has no interface. */
- 1};
-
-/* Only display ip forwarding is enabled or not. */
-DEFUN (show_ip_forwarding,
- show_ip_forwarding_cmd,
- "show ip forwarding",
- SHOW_STR
- IP_STR
- "IP forwarding status\n")
-{
- int ret;
-
- ret = ipforward();
-
- if (ret == 0)
- vty_out(vty, "IP forwarding is off\n");
- else
- vty_out(vty, "IP forwarding is on\n");
- return CMD_SUCCESS;
-}
-
-/* Only display ipv6 forwarding is enabled or not. */
-DEFUN (show_ipv6_forwarding,
- show_ipv6_forwarding_cmd,
- "show ipv6 forwarding",
- SHOW_STR
- "IPv6 information\n"
- "Forwarding status\n")
-{
- int ret;
-
- ret = ipforward_ipv6();
-
- switch (ret) {
- case -1:
- vty_out(vty, "ipv6 forwarding is unknown\n");
- break;
- case 0:
- vty_out(vty, "ipv6 forwarding is %s\n", "off");
- break;
- case 1:
- vty_out(vty, "ipv6 forwarding is %s\n", "on");
- break;
- default:
- vty_out(vty, "ipv6 forwarding is %s\n", "off");
- break;
- }
- return CMD_SUCCESS;
-}
-
-DEFUN (ipv6_forwarding,
- ipv6_forwarding_cmd,
- "ipv6 forwarding",
- IPV6_STR
- "Turn on IPv6 forwarding\n")
-{
- int ret;
-
- ret = ipforward_ipv6();
- if (ret == 0)
- ret = ipforward_ipv6_on();
-
- if (ret == 0) {
- vty_out(vty, "Can't turn on IPv6 forwarding\n");
- return CMD_WARNING_CONFIG_FAILED;
- }
-
- return CMD_SUCCESS;
-}
-
-DEFUN (no_ipv6_forwarding,
- no_ipv6_forwarding_cmd,
- "no ipv6 forwarding",
- NO_STR
- IPV6_STR
- "Turn off IPv6 forwarding\n")
-{
- int ret;
-
- ret = ipforward_ipv6();
- if (ret != 0)
- ret = ipforward_ipv6_off();
-
- if (ret != 0) {
- vty_out(vty, "Can't turn off IPv6 forwarding\n");
- return CMD_WARNING_CONFIG_FAILED;
- }
-
- return CMD_SUCCESS;
-}
-
-/* IPForwarding configuration write function. */
-static int config_write_forwarding(struct vty *vty)
-{
- /* FIXME: Find better place for that. */
- router_id_write(vty);
-
- if (!ipforward())
- vty_out(vty, "no ip forwarding\n");
- if (!ipforward_ipv6())
- vty_out(vty, "no ipv6 forwarding\n");
- vty_out(vty, "!\n");
- return 0;
-}
-
-/* table node for routing tables. */
-static struct cmd_node forwarding_node = {FORWARDING_NODE,
- "", /* This node has no interface. */
- 1};
-
#if defined(HANDLE_ZAPI_FUZZING)
void zserv_read_file(char *input)
{
}
#endif
-/* Initialisation of zebra and installation of commands. */
-void zebra_init(void)
+void zserv_init(void)
{
/* Client list init. */
zebrad.client_list = list_new();
zebrad.client_list->del = (void (*)(void *))zebra_client_free;
- /* Install configuration write function. */
- install_node(&table_node, config_write_table);
- install_node(&forwarding_node, config_write_forwarding);
-
- install_element(VIEW_NODE, &show_ip_forwarding_cmd);
- install_element(CONFIG_NODE, &ip_forwarding_cmd);
- install_element(CONFIG_NODE, &no_ip_forwarding_cmd);
- install_element(ENABLE_NODE, &show_zebra_cmd);
install_element(ENABLE_NODE, &show_zebra_client_cmd);
install_element(ENABLE_NODE, &show_zebra_client_summary_cmd);
-
-#ifdef HAVE_NETLINK
- install_element(VIEW_NODE, &show_table_cmd);
- install_element(CONFIG_NODE, &config_table_cmd);
- install_element(CONFIG_NODE, &no_config_table_cmd);
-#endif /* HAVE_NETLINK */
-
- install_element(VIEW_NODE, &show_ipv6_forwarding_cmd);
- install_element(CONFIG_NODE, &ipv6_forwarding_cmd);
- install_element(CONFIG_NODE, &no_ipv6_forwarding_cmd);
-
- /* Route-map */
- zebra_route_map_init();
}
extern unsigned int multipath_num;
/* Prototypes. */
-extern void zebra_init(void);
-extern void zebra_if_init(void);
+extern void zserv_init(void);
extern void zebra_zserv_socket_init(char *path);
-extern void hostinfo_get(void);
-extern void rib_init(void);
-extern void interface_list(struct zebra_ns *);
-extern void route_read(struct zebra_ns *);
-extern void macfdb_read(struct zebra_ns *);
-extern void macfdb_read_for_bridge(struct zebra_ns *, struct interface *,
- struct interface *);
-extern void neigh_read(struct zebra_ns *);
-extern void neigh_read_for_vlan(struct zebra_ns *, struct interface *);
-extern void kernel_init(struct zebra_ns *);
-extern void kernel_terminate(struct zebra_ns *);
-extern void zebra_route_map_init(void);
-extern void zebra_vty_init(void);
extern int zsend_vrf_add(struct zserv *, struct zebra_vrf *);
extern int zsend_vrf_delete(struct zserv *, struct zebra_vrf *);
vrf_id_t vrf_id, struct prefix *p,
enum zapi_route_notify_owner note);
-extern pid_t pid;
-
extern void zserv_create_header(struct stream *s, uint16_t cmd,
vrf_id_t vrf_id);
extern void zserv_nexthop_num_warn(const char *, const struct prefix *,