void ptm_bfd_ses_up(struct bfd_session *bfd)
{
+ int old_state = bfd->ses_state;
+
bfd->local_diag = 0;
bfd->ses_state = PTM_BFD_UP;
bfd->polling = 1;
control_notify(bfd);
- INFOLOG("Session 0x%x up peer %s", bfd->discrs.my_discr,
- satostr(&bfd->shop.peer));
+ if (old_state != bfd->ses_state)
+ log_info("state-change: [%s] %s -> %s", bs_to_string(bfd),
+ state_list[old_state].str,
+ state_list[bfd->ses_state].str);
}
void ptm_bfd_ses_dn(struct bfd_session *bfd, uint8_t diag)
if (old_state == PTM_BFD_UP)
control_notify(bfd);
- INFOLOG("Session 0x%x down peer %s Rsn %s prev st %s",
- bfd->discrs.my_discr, satostr(&bfd->shop.peer),
- get_diag_str(bfd->local_diag), state_list[old_state].str);
-
/* Stop echo packet transmission if they are active */
if (BFD_CHECK_FLAG(bfd->flags, BFD_SESS_FLAG_ECHO_ACTIVE))
ptm_bfd_echo_stop(bfd, 0);
+
+ if (old_state != bfd->ses_state)
+ log_info("state-change: [%s] %s -> %s reason:%s",
+ bs_to_string(bfd), state_list[old_state].str,
+ state_list[bfd->ses_state].str,
+ get_diag_str(bfd->local_diag));
}
static int ptm_bfd_get_vrf_name(char *port_name, char *vrf_name)
} else if (port_name && port_name[0]) {
memset(vrf_buf, 0, sizeof(vrf_buf));
if (ptm_bfd_get_vrf_name(port_name, vrf_buf) != -1)
- strlcpy(mhop.vrf_name, vrf_buf, sizeof(mhop.vrf_name));
+ strlcpy(mhop.vrf_name, vrf_buf,
+ sizeof(mhop.vrf_name));
}
l_bfd = bfd_mhop_lookup(mhop);
memset(&shop, 0, sizeof(shop));
shop.peer = *peer;
if (port_name && port_name[0])
- strlcpy(shop.port_name, port_name, sizeof(shop.port_name));
+ strlcpy(shop.port_name, port_name,
+ sizeof(shop.port_name));
l_bfd = bfd_shop_lookup(shop);
}
int bfd_recvtimer_cb(struct thread *t)
{
struct bfd_session *bs = THREAD_ARG(t);
- uint8_t old_state;
-
- old_state = bs->ses_state;
switch (bs->ses_state) {
case PTM_BFD_INIT:
case PTM_BFD_UP:
ptm_bfd_ses_dn(bs, BFD_DIAGDETECTTIME);
- INFOLOG("%s Detect timeout on session 0x%x with peer %s, in state %d",
- __func__, bs->discrs.my_discr, satostr(&bs->shop.peer),
- bs->ses_state);
bfd_recvtimer_update(bs);
break;
break;
}
- if (old_state != bs->ses_state) {
- DLOG("BFD Sess %d [%s] Old State [%s] : New State [%s]",
- bs->discrs.my_discr, satostr(&bs->shop.peer),
- state_list[old_state].str, state_list[bs->ses_state].str);
- }
-
return 0;
}
int bfd_echo_recvtimer_cb(struct thread *t)
{
struct bfd_session *bs = THREAD_ARG(t);
- uint8_t old_state;
-
- old_state = bs->ses_state;
switch (bs->ses_state) {
case PTM_BFD_INIT:
case PTM_BFD_UP:
ptm_bfd_ses_dn(bs, BFD_DIAGDETECTTIME);
- INFOLOG("%s Detect timeout on session 0x%x with peer %s, in state %d",
- __func__, bs->discrs.my_discr, satostr(&bs->shop.peer),
- bs->ses_state);
break;
}
- if (old_state != bs->ses_state) {
- DLOG("BFD Sess %d [%s] Old State [%s] : New State [%s]",
- bs->discrs.my_discr, satostr(&bs->shop.peer),
- state_list[old_state].str, state_list[bs->ses_state].str);
- }
-
return 0;
}
*/
if (bpc->bpc_ipv4) {
psock = bp_peer_socket(bpc);
- if (psock == -1) {
- ERRLOG("Can't get socket for new session: %s",
- strerror(errno));
+ if (psock == -1)
return NULL;
- }
} else {
psock = bp_peer_socketv6(bpc);
- if (psock == -1) {
- ERRLOG("Can't get IPv6 socket for new session: %s",
- strerror(errno));
+ if (psock == -1)
return NULL;
- }
}
/* Get memory */
bfd = bfd_session_new(psock);
if (bfd == NULL) {
- ERRLOG("Can't malloc memory for new session: %s",
- strerror(errno));
+ log_error("session-new: allocation failed");
return NULL;
}
ptm_bfd_xmt_TO(bfd, 0);
- if (bpc->bpc_mhop) {
- INFOLOG("Created new session 0x%x with vrf %s peer %s local %s",
- bfd->discrs.my_discr,
- (bpc->bpc_has_vrfname) ? bfd->mhop.vrf_name : "N/A",
- satostr(&bfd->mhop.peer), satostr(&bfd->mhop.local));
- } else {
- INFOLOG("Created new session 0x%x with peer %s port %s",
- bfd->discrs.my_discr, satostr(&bfd->shop.peer),
- bfd->shop.port_name[0] ? bfd->shop.port_name : "N/A");
- }
+ log_info("session-new: %s", bs_to_string(bfd));
control_notify_config(BCM_NOTIFY_CONFIG_ADD, bfd);
/* This pointer is being referenced, don't let it be deleted. */
if (bs->refcount > 0) {
- zlog_debug("%s: trying to free in-use session: %" PRIu64
- " references",
- __func__, bs->refcount);
+ log_error("session-delete: refcount failure: %" PRIu64
+ " references",
+ bs->refcount);
return -1;
}
- if (BFD_CHECK_FLAG(bs->flags, BFD_SESS_FLAG_MH)) {
- INFOLOG("Deleting session 0x%x with vrf %s peer %s local %s",
- bs->discrs.my_discr,
- bpc->bpc_has_vrfname ? bpc->bpc_vrfname : "N/A",
- satostr(&bs->mhop.peer), satostr(&bs->mhop.local));
- } else {
- INFOLOG("Deleting session 0x%x with peer %s port %s",
- bs->discrs.my_discr, satostr(&bs->shop.peer),
- bs->shop.port_name);
- }
+ log_info("session-delete: %s", bs_to_string(bs));
control_notify_config(BCM_NOTIFY_CONFIG_DELETE, bs);
snprintf(buf, buflen, "%u second(s)", second);
}
+const char *bs_to_string(struct bfd_session *bs)
+{
+ static char buf[256];
+ int pos;
+ bool is_mhop = BFD_CHECK_FLAG(bs->flags, BFD_SESS_FLAG_MH);
+
+ pos = snprintf(buf, sizeof(buf), "mhop:%s", is_mhop ? "yes" : "no");
+ if (BFD_CHECK_FLAG(bs->flags, BFD_SESS_FLAG_MH)) {
+ pos += snprintf(buf + pos, sizeof(buf) - pos,
+ " peer:%s local:%s", satostr(&bs->mhop.peer),
+ satostr(&bs->mhop.local));
+
+ if (bs->mhop.vrf_name[0])
+ snprintf(buf + pos, sizeof(buf) - pos, " vrf:%s",
+ bs->mhop.vrf_name);
+ } else {
+ pos += snprintf(buf + pos, sizeof(buf) - pos, " peer:%s",
+ satostr(&bs->shop.peer));
+
+ if (bs->local_address.sa_sin.sin_family)
+ pos += snprintf(buf + pos, sizeof(buf) - pos,
+ " local:%s",
+ satostr(&bs->local_address));
+
+ if (bs->shop.port_name[0])
+ snprintf(buf + pos, sizeof(buf) - pos, " interface:%s",
+ bs->shop.port_name);
+ }
+
+ return buf;
+}
+
/*
* BFD hash data structures to find sessions.
return 0;
}
-
/*
* Hash public interface / exported functions.
*/
* TODO: implement layer 2 send for *BSDs. This is
* needed for VxLAN.
*/
- log_warning("%s: not implemented");
+ log_warning("packet-send: not implemented");
return -1;
#endif
} else if (BFD_CHECK_FLAG(bs->flags, BFD_SESS_FLAG_IPV6)) {
#endif /* HAVE_STRUCT_SOCKADDR_SA_LEN */
rv = sendto(sd, data, datalen, 0, sa, slen);
if (rv <= 0) {
- log_debug("%s:%d: sendto: (%d) %s", __func__, __LINE__, errno,
- strerror(errno));
+ log_debug("packet-send: send failure: %s", strerror(errno));
return -1;
}
- if (rv < (ssize_t)datalen) {
- log_debug("%s:%d: sendto: sent partial data", __func__,
- __LINE__);
- }
+ if (rv < (ssize_t)datalen)
+ log_debug("packet-send: send partial", strerror(errno));
return 0;
}
}
if (_ptm_bfd_send(bfd, use_layer2, &port, pkt, pktlen) != 0) {
- ERRLOG("%s: _ptm_bfd_send: %s", __func__, strerror(errno));
+ log_debug("echo-packet: send failure: %s", strerror(errno));
return;
}
#endif /* BFD_BSD_FILTER */
if (sendto(bglobal.bg_echo, pkt, pkt_len, 0, ss, sslen) < 0) {
- ERRLOG("%s: sendto: %s", __func__, strerror(errno));
+ log_debug("echo-loopback: send failure: %s", strerror(errno));
return -1;
}
(struct sockaddr *)&ss, &sslen);
if (pkt_len <= 0) {
if (errno != EAGAIN)
- ERRLOG("%s: recvfrom: %s", __func__, strerror(errno));
+ log_error("echo-packet: read failure: %s",
+ strerror(errno));
+
return -1;
}
/* Check if we have at least the basic headers to send back. */
- if (pkt_len < HEADERS_MIN_LEN) {
- INFOLOG("Received short echo packet");
+ if (pkt_len < BFD_ECHO_PKT_TOT_LEN) {
+ log_debug("echo-packet: too short (got %ld, expected %d)",
+ pkt_len, BFD_ECHO_PKT_TOT_LEN);
return -1;
}
(struct sockaddr *)&ss,
sizeof(struct sockaddr_ll));
- /* Packet is too small for us to process */
- if (pkt_len < BFD_ECHO_PKT_TOT_LEN) {
- INFOLOG("Received short echo packet");
- return -1;
- }
-
my_discr = ntohl(ep->data.my_discr);
if (ep->data.my_discr == 0) {
- INFOLOG("My discriminator is zero in echo pkt from 0x%x",
- ntohl(ep->ip.saddr));
+ log_debug("echo-packet: 'my discriminator' is zero");
return -1;
}
#endif /* BFD_LINUX */
/* Your discriminator not zero - use it to find session */
bfd = bfd_id_lookup(my_discr);
if (bfd == NULL) {
- INFOLOG("Failed to extract session from echo packet");
+ log_debug("echo-packet: no matching session (id:%u)", my_discr);
return -1;
}
if (!BFD_CHECK_FLAG(bfd->flags, BFD_SESS_FLAG_ECHO_ACTIVE)) {
- INFOLOG("BFD echo not active - ignore echo packet");
+ log_debug("echo-packet: echo disabled [%s]", my_discr,
+ bs_to_string(bfd));
return -1;
}
}
cp.timers.required_min_echo = htonl(bfd->timers.required_min_echo);
- if (_ptm_bfd_send(bfd, false, NULL, &cp, BFD_PKT_LEN) != 0) {
- ERRLOG("Error sending control pkt: %s", strerror(errno));
+ if (_ptm_bfd_send(bfd, false, NULL, &cp, BFD_PKT_LEN) != 0)
return;
- }
bfd->stats.tx_ctrl_pkt++;
}
struct bfd_session_vxlan_info *vxlan_info)
{
if (bfd->vxlan_info.check_tnl_key && (vxlan_info->vnid != 0)) {
- ERRLOG("Error Rx BFD Vxlan pkt with non-zero vnid %d",
- vxlan_info->vnid);
+ log_error("vxlan-packet: vnid not zero: %d", vxlan_info->vnid);
return false;
}
if (bfd->vxlan_info.local_dst_ip.s_addr
!= vxlan_info->local_dst_ip.s_addr) {
- ERRLOG("Error Rx BFD Vxlan pkt with wrong inner dst IP %s",
- inet_ntoa(vxlan_info->local_dst_ip));
+ log_error("vxlan-packet: wrong inner destination",
+ inet_ntoa(vxlan_info->local_dst_ip));
return false;
}
if (memcmp(bfd->vxlan_info.local_dst_mac, vxlan_info->local_dst_mac,
ETHERNET_ADDRESS_LENGTH)) {
- ERRLOG("Error Rx BFD Vxlan pkt with wrong inner dst MAC %02x:%02x:%02x:%02x:%02x:%02x",
- vxlan_info->local_dst_mac[0],
- vxlan_info->local_dst_mac[1],
- vxlan_info->local_dst_mac[2],
- vxlan_info->local_dst_mac[3],
- vxlan_info->local_dst_mac[4],
- vxlan_info->local_dst_mac[5]);
+ log_error(
+ "vxlan-packet: wrong inner mac: %02x:%02x:%02x:%02x:%02x:%02x",
+ vxlan_info->local_dst_mac[0],
+ vxlan_info->local_dst_mac[1],
+ vxlan_info->local_dst_mac[2],
+ vxlan_info->local_dst_mac[3],
+ vxlan_info->local_dst_mac[4],
+ vxlan_info->local_dst_mac[5]);
return false;
}
mlen = recvmsg(sd, &msghdr, MSG_DONTWAIT);
if (mlen == -1) {
- if (errno != EAGAIN) {
- ERRLOG("Error receiving from BFD socket: %s",
- strerror(errno));
- }
+ if (errno != EAGAIN)
+ log_error("ipv4-recv: recv failed: %s",
+ strerror(errno));
+
return -1;
}
memcpy(&ttl, CMSG_DATA(cm), sizeof(ttl));
if ((is_mhop == false) && (ttl != BFD_TTL_VAL)) {
- INFOLOG("Received pkt with invalid TTL %u from %s flags: %d",
- ttl, satostr(peer), msghdr.msg_flags);
+ log_debug(
+ "ipv4-recv: invalid TTL from %s (expected %d, got %d flags %d)",
+ satostr(peer), ttl, BFD_TTL_VAL,
+ msghdr.msg_flags);
return -1;
}
break;
memcpy(&ttl, CMSG_DATA(cm), sizeof(ttl));
if ((is_mhop == false) && (ttl != BFD_TTL_VAL)) {
- INFOLOG("Received pkt with invalid TTL %u from %s flags: %d",
- ttl, satostr(peer), msghdr.msg_flags);
+ log_debug(
+ "ipv4-recv: invalid TTL from %s (expected %d, got %d flags %d)",
+ satostr(peer), ttl, BFD_TTL_VAL,
+ msghdr.msg_flags);
return -1;
}
break;
mlen = recvmsg(sd, &msghdr6, MSG_DONTWAIT);
if (mlen == -1) {
- if (errno != EAGAIN) {
- ERRLOG("Error receiving from BFD socket: %s",
- strerror(errno));
- }
+ if (errno != EAGAIN)
+ log_error("ipv4-recv: recv failed: %s",
+ strerror(errno));
+
return -1;
}
if (cm->cmsg_type == IPV6_HOPLIMIT) {
memcpy(&ttlval, CMSG_DATA(cm), 4);
if ((is_mhop == false) && (ttlval != BFD_TTL_VAL)) {
- INFOLOG("Received pkt with invalid TTL %u from %s flags: %d",
- ttlval, satostr(peer),
+ log_debug(
+ "ipv6-recv: invalid TTL from %s (expected %d, got %d flags %d)",
+ satostr(peer), ttlval, BFD_TTL_VAL,
msghdr.msg_flags);
return -1;
}
}
}
+static void cp_debug(bool mhop, struct sockaddr_any *peer,
+ struct sockaddr_any *local, const char *port,
+ const char *vrf, const char *fmt, ...)
+{
+ char buf[512], peerstr[128], localstr[128], portstr[64], vrfstr[64];
+ va_list vl;
+
+ if (peer->sa_sin.sin_family)
+ snprintf(peerstr, sizeof(peerstr), " peer:%s", satostr(peer));
+ else
+ peerstr[0] = 0;
+
+ if (local->sa_sin.sin_family)
+ snprintf(localstr, sizeof(localstr), " local:%s",
+ satostr(local));
+ else
+ localstr[0] = 0;
+
+ if (port[0])
+ snprintf(portstr, sizeof(portstr), " port:%s", port);
+ else
+ portstr[0] = 0;
+
+ if (vrf[0])
+ snprintf(vrfstr, sizeof(vrfstr), " vrf:%s", port);
+ else
+ vrfstr[0] = 0;
+
+ va_start(vl, fmt);
+ vsnprintf(buf, sizeof(buf), fmt, vl);
+ va_end(vl);
+
+ log_debug("control-packet: %s [mhop:%s%s%s%s%s]", buf,
+ mhop ? "yes" : "no", peerstr, localstr, portstr, vrfstr);
+}
+
int bfd_recv_cb(struct thread *t)
{
int sd = THREAD_FD(t);
struct bfd_pkt *cp;
bool is_mhop, is_vxlan;
ssize_t mlen = 0;
- uint8_t old_state;
uint32_t oldEchoXmt_TO, oldXmtTime;
struct sockaddr_any local, peer;
char port[MAXNAMELEN + 1], vrfname[MAXNAMELEN + 1];
/* Schedule next read. */
bfd_sd_reschedule(sd);
+ /* Handle echo packets. */
if (sd == bglobal.bg_echo) {
ptm_bfd_process_echo_pkt(sd);
return 0;
}
+ /* Handle control packets. */
is_mhop = is_vxlan = false;
if (sd == bglobal.bg_shop || sd == bglobal.bg_mhop) {
is_mhop = sd == bglobal.bg_mhop;
/* Implement RFC 5880 6.8.6 */
if (mlen < BFD_PKT_LEN) {
- INFOLOG("Received short packet from %s", satostr(&peer));
+ cp_debug(is_mhop, &peer, &local, port, vrfname,
+ "too small (%ld bytes)", mlen);
return 0;
}
+ /*
+ * Parse the control header for inconsistencies:
+ * - Invalid version;
+ * - Bad multiplier configuration;
+ * - Short packets;
+ * - Invalid discriminator;
+ */
cp = (struct bfd_pkt *)(msghdr.msg_iov->iov_base);
if (BFD_GETVER(cp->diag) != BFD_VERSION) {
- INFOLOG("Received bad version %d from %s", BFD_GETVER(cp->diag),
- satostr(&peer));
+ cp_debug(is_mhop, &peer, &local, port, vrfname,
+ "bad version %d", BFD_GETVER(cp->diag));
return 0;
}
if (cp->detect_mult == 0) {
- INFOLOG("Detect Mult is zero in pkt from %s", satostr(&peer));
+ cp_debug(is_mhop, &peer, &local, port, vrfname,
+ "detect multiplier set to zero");
return 0;
}
if ((cp->len < BFD_PKT_LEN) || (cp->len > mlen)) {
- INFOLOG("Invalid length %d in control pkt from %s", cp->len,
- satostr(&peer));
+ cp_debug(is_mhop, &peer, &local, port, vrfname, "too small");
return 0;
}
if (cp->discrs.my_discr == 0) {
- INFOLOG("My discriminator is zero in pkt from %s",
- satostr(&peer));
+ cp_debug(is_mhop, &peer, &local, port, vrfname,
+ "'my discriminator' is zero");
return 0;
}
+ /* Find the session that this packet belongs. */
bfd = ptm_bfd_sess_find(cp, port, &peer, &local, vrfname, is_mhop);
if (bfd == NULL) {
- DLOG("Failed to generate session from remote packet");
+ cp_debug(is_mhop, &peer, &local, port, vrfname,
+ "no session found");
return 0;
}
+ /* Handle VxLAN cases. */
if (is_vxlan && !ptm_bfd_validate_vxlan_pkt(bfd, &vxlan_info))
return 0;
bfd->stats.rx_ctrl_pkt++;
+
+ /*
+ * Multi hop: validate packet TTL.
+ * Single hop: set local address that received the packet.
+ */
if (is_mhop) {
if ((BFD_TTL_VAL - bfd->mh_ttl) > ttlval) {
- DLOG("Exceeded max hop count of %d, dropped pkt from %s with TTL %d",
- bfd->mh_ttl, satostr(&peer), ttlval);
+ cp_debug(is_mhop, &peer, &local, port, vrfname,
+ "exceeded max hop count (expected %d, got %d)",
+ bfd->mh_ttl, ttlval);
return 0;
}
} else if (bfd->local_ip.sa_sin.sin_family == AF_UNSPEC) {
if (bfd->ifindex == 0)
bfd->ifindex = ptm_bfd_fetch_ifindex(port);
+ /* Log remote discriminator changes. */
if ((bfd->discrs.remote_discr != 0)
- && (bfd->discrs.remote_discr != ntohl(cp->discrs.my_discr))) {
- DLOG("My Discriminator mismatch in pkt from %s, Expected %d Got %d",
- satostr(&peer), bfd->discrs.remote_discr,
- ntohl(cp->discrs.my_discr));
- }
+ && (bfd->discrs.remote_discr != ntohl(cp->discrs.my_discr)))
+ cp_debug(is_mhop, &peer, &local, port, vrfname,
+ "remote discriminator mismatch (expected %d, got %d)",
+ bfd->discrs.remote_discr, ntohl(cp->discrs.my_discr));
bfd->discrs.remote_discr = ntohl(cp->discrs.my_discr);
? bfd->timers.required_min_rx
: ntohl(cp->timers.desired_min_tx));
bfd->remote_detect_mult = cp->detect_mult;
- } else {
- ERRLOG("Unsupport BFD mode detected");
- }
+ } else
+ cp_debug(is_mhop, &peer, &local, port, vrfname,
+ "unsupported demand mode");
/* Save remote diagnostics before state switch. */
bfd->remote_diag = cp->diag & BFD_DIAGMASK;
/* State switch from section 6.8.6 */
- old_state = bfd->ses_state;
if (BFD_GETSTATE(cp->flags) == PTM_BFD_ADM_DOWN) {
if (bfd->ses_state != PTM_BFD_DOWN)
ptm_bfd_ses_dn(bfd, BFD_DIAGNEIGHDOWN);
}
}
- if (old_state != bfd->ses_state) {
- DLOG("BFD Sess %d [%s] Old State [%s] : New State [%s]",
- bfd->discrs.my_discr, satostr(&peer),
- state_list[old_state].str, state_list[bfd->ses_state].str);
- }
-
+ /*
+ * Handle echo packet status:
+ * - Start echo packets if configured and permitted
+ * (required_min_echo > 0);
+ * - Stop echo packets if not allowed (required_min_echo == 0);
+ * - Recalculate echo packet interval;
+ */
if (BFD_CHECK_FLAG(bfd->flags, BFD_SESS_FLAG_ECHO)) {
if (BFD_CHECK_FLAG(bfd->flags, BFD_SESS_FLAG_ECHO_ACTIVE)) {
if (!ntohl(cp->timers.required_min_echo)) {
ptm_bfd_start_xmt_timer(bfd, false);
}
- if (!bfd->demand_mode) {
- /* Restart detection timer (packet received) */
+ /* Restart detection timer (packet received) */
+ if (!bfd->demand_mode)
bfd_recvtimer_update(bfd);
- } else {
- ERRLOG("Unsupport BFD mode detected");
- }
/*
* Save the timers and state sent by the remote end
static int srcPort = BFD_SRCPORTINIT;
sd = socket(AF_INET, SOCK_DGRAM, PF_UNSPEC);
- if (sd == -1)
+ if (sd == -1) {
+ log_error("ipv4-new: failed to create socket: %s",
+ strerror(errno));
return -1;
+ }
if (!bpc->bpc_has_vxlan) {
/* Set TTL to 255 for all transmitted packets */
do {
if ((++pcount) > (BFD_SRCPORTMAX - BFD_SRCPORTINIT)) {
/* Searched all ports, none available */
- ERRLOG("Can't find source port for new session: %s",
- strerror(errno));
+ log_error("ipv4-new: failed to bind port: %s",
+ strerror(errno));
close(sd);
return -1;
}
static int srcPort = BFD_SRCPORTINIT;
sd = socket(AF_INET6, SOCK_DGRAM, PF_UNSPEC);
- if (sd == -1)
+ if (sd == -1) {
+ log_error("ipv6-new: failed to create socket: %s",
+ strerror(errno));
return -1;
+ }
if (!bpc->bpc_has_vxlan) {
/* Set TTL to 255 for all transmitted packets */
do {
if ((++pcount) > (BFD_SRCPORTMAX - BFD_SRCPORTINIT)) {
/* Searched all ports, none available */
- ERRLOG("Can't find source port for new session: %s",
- strerror(errno));
+ log_error("ipv6-new: failed to bind port: %s",
+ strerror(errno));
close(sd);
return -1;
}