const char ZEBRA_PTM_BFD_MAX_HOP_CNT_FIELD[] = "maxHopCnt";
const char ZEBRA_PTM_BFD_SEND_EVENT[] = "sendEvent";
const char ZEBRA_PTM_BFD_VRF_NAME_FIELD[] = "vrfName";
+const char ZEBRA_PTM_BFD_CBIT_FIELD[] = "bfdcbit";
static ptm_lib_handle_t *ptm_hdl;
ptm_cb.t_timer = NULL;
thread_add_timer(zrouter.master, zebra_ptm_connect, NULL,
ptm_cb.reconnect_time, &ptm_cb.t_timer);
- return (-1);
+ return -1;
case BUFFER_PENDING:
ptm_cb.t_write = NULL;
thread_add_write(zrouter.master, zebra_ptm_flush_messages, NULL,
break;
}
- return (0);
+ return 0;
}
static int zebra_ptm_send_message(char *data, int size)
thread_add_timer(zrouter.master, zebra_ptm_connect, NULL,
ptm_cb.reconnect_time,
&ptm_cb.t_timer);
- return (-1);
+ return -1;
}
ptm_cb.t_read = NULL;
char tmp_buf[64];
int data_len = ZEBRA_PTM_SEND_MAX_SOCKBUF;
unsigned int pid;
+ uint8_t cbit_set;
if (hdr->command == ZEBRA_BFD_DEST_UPDATE)
client->bfd_peer_upd8_cnt++;
ptm_lib_append_msg(ptm_hdl, out_ctxt,
ZEBRA_PTM_BFD_IFNAME_FIELD, if_name);
}
+ STREAM_GETC(s, cbit_set);
+ sprintf(tmp_buf, "%d", cbit_set);
+ ptm_lib_append_msg(ptm_hdl, out_ctxt,
+ ZEBRA_PTM_BFD_CBIT_FIELD, tmp_buf);
sprintf(tmp_buf, "%d", 1);
ptm_lib_append_msg(ptm_hdl, out_ctxt, ZEBRA_PTM_BFD_SEND_EVENT,
static void zebra_ptm_send_bfdd(struct stream *msg);
static void zebra_ptm_send_clients(struct stream *msg);
static int _zebra_ptm_bfd_client_deregister(struct zserv *zs);
-static void _zebra_ptm_reroute(struct zserv *zs, struct stream *msg,
- uint32_t command);
+static void _zebra_ptm_reroute(struct zserv *zs, struct zebra_vrf *zvrf,
+ struct stream *msg, uint32_t command);
/*
/*
* Message handling.
*/
-static void _zebra_ptm_reroute(struct zserv *zs, struct stream *msg,
- uint32_t command)
+static void _zebra_ptm_reroute(struct zserv *zs, struct zebra_vrf *zvrf,
+ struct stream *msg, uint32_t command)
{
struct stream *msgc;
- size_t zmsglen, zhdrlen;
+ char buf[ZEBRA_MAX_PACKET_SIZ];
pid_t ppid;
- /*
- * Don't modify message in the zebra API. In order to do that we
- * need to allocate a new message stream and copy the message
- * provided by zebra.
- */
+ /* Create BFD header */
msgc = stream_new(ZEBRA_MAX_PACKET_SIZ);
- if (msgc == NULL) {
- zlog_debug("%s: not enough memory", __func__);
- return;
- }
+ zclient_create_header(msgc, ZEBRA_BFD_DEST_REPLAY, zvrf->vrf->vrf_id);
+ stream_putl(msgc, command);
- /* Calculate our header size plus the message contents. */
- zhdrlen = ZEBRA_HEADER_SIZE + sizeof(uint32_t);
- zmsglen = msg->endp - msg->getp;
- memcpy(msgc->data + zhdrlen, msg->data + msg->getp, zmsglen);
+ if (STREAM_READABLE(msg) > STREAM_WRITEABLE(msgc)) {
+ zlog_warn("Cannot fit extended BFD header plus original message contents into ZAPI packet; dropping message");
+ goto stream_failure;
+ }
- /*
- * The message type will be BFD_DEST_REPLY so we can use only
- * one callback at the `bfdd` side, however the real command
- * number will be included right after the zebra header.
- */
- zclient_create_header(msgc, ZEBRA_BFD_DEST_REPLAY, 0);
- stream_putl(msgc, command);
+ /* Copy original message, excluding header, into new message */
+ stream_get_from(buf, msg, stream_get_getp(msg), STREAM_READABLE(msg));
+ stream_put(msgc, buf, STREAM_READABLE(msg));
- /* Update the data pointers. */
- msgc->getp = 0;
- msgc->endp = zhdrlen + zmsglen;
- stream_putw_at(msgc, 0, stream_get_endp(msgc));
+ /* Update length field */
+ stream_putw_at(msgc, 0, STREAM_READABLE(msgc));
zebra_ptm_send_bfdd(msgc);
+ msgc = NULL;
/* Registrate process PID for shutdown hook. */
STREAM_GETL(msg, ppid);
return;
stream_failure:
+ if (msgc)
+ stream_free(msgc);
zlog_err("%s:%d failed to registrate client pid", __FILE__, __LINE__);
}
zlog_debug("bfd_dst_register msg from client %s: length=%d",
zebra_route_string(client->proto), hdr->length);
- _zebra_ptm_reroute(client, msg, ZEBRA_BFD_DEST_REGISTER);
+ _zebra_ptm_reroute(client, zvrf, msg, ZEBRA_BFD_DEST_REGISTER);
}
void zebra_ptm_bfd_dst_deregister(ZAPI_HANDLER_ARGS)
zlog_debug("bfd_dst_deregister msg from client %s: length=%d",
zebra_route_string(client->proto), hdr->length);
- _zebra_ptm_reroute(client, msg, ZEBRA_BFD_DEST_DEREGISTER);
+ _zebra_ptm_reroute(client, zvrf, msg, ZEBRA_BFD_DEST_DEREGISTER);
}
void zebra_ptm_bfd_client_register(ZAPI_HANDLER_ARGS)
zlog_debug("bfd_client_register msg from client %s: length=%d",
zebra_route_string(client->proto), hdr->length);
- _zebra_ptm_reroute(client, msg, ZEBRA_BFD_CLIENT_REGISTER);
+ _zebra_ptm_reroute(client, zvrf, msg, ZEBRA_BFD_CLIENT_REGISTER);
}
void zebra_ptm_bfd_dst_replay(ZAPI_HANDLER_ARGS)
* special treatment.
*/
if (client->proto != ZEBRA_ROUTE_BFD) {
- _zebra_ptm_reroute(client, msg, ZEBRA_BFD_DEST_REPLAY);
+ _zebra_ptm_reroute(client, zvrf, msg, ZEBRA_BFD_DEST_REPLAY);
return;
}