don't connect on first hello, there are chances that ours is not seen yet
setproctitle with ldp id - useful for rump kernels testing fix a memory leak in ldp_peer_new don't holddown if already holded down peer sockets are now non-blocking connected routes deletes are now processed check if peer is connected before attempting to sending label mappings
This commit is contained in:
parent
83b16e7e52
commit
ae8b7d0074
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: fsm.c,v 1.13 2013/07/12 08:55:52 kefren Exp $ */
|
/* $NetBSD: fsm.c,v 1.14 2013/07/20 05:16:08 kefren Exp $ */
|
||||||
|
|
||||||
/*-
|
/*-
|
||||||
* Copyright (c) 2010 The NetBSD Foundation, Inc.
|
* Copyright (c) 2010 The NetBSD Foundation, Inc.
|
||||||
|
@ -112,6 +112,7 @@ run_ldp_hello(const struct ldp_pdu * pduid, const struct hello_tlv * ht,
|
||||||
hi->ldp_id.s_addr = pduid->ldp_id.s_addr;
|
hi->ldp_id.s_addr = pduid->ldp_id.s_addr;
|
||||||
memcpy(&hi->transport_address, &traddr, traddr.sa.sa_len);
|
memcpy(&hi->transport_address, &traddr, traddr.sa.sa_len);
|
||||||
SLIST_INSERT_HEAD(&hello_info_head, hi, infos);
|
SLIST_INSERT_HEAD(&hello_info_head, hi, infos);
|
||||||
|
may_connect = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Update expire timer */
|
/* Update expire timer */
|
||||||
|
@ -236,5 +237,6 @@ set_my_ldp_id()
|
||||||
freeifaddrs(ifa);
|
freeifaddrs(ifa);
|
||||||
debugp("LDP ID: %s\n", inet_ntoa(a));
|
debugp("LDP ID: %s\n", inet_ntoa(a));
|
||||||
strlcpy(my_ldp_id, inet_ntoa(a), INET_ADDRSTRLEN);
|
strlcpy(my_ldp_id, inet_ntoa(a), INET_ADDRSTRLEN);
|
||||||
|
setproctitle("LDP ID: %s", my_ldp_id);
|
||||||
return LDP_E_OK;
|
return LDP_E_OK;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: ldp_peer.c,v 1.14 2013/07/18 06:07:45 kefren Exp $ */
|
/* $NetBSD: ldp_peer.c,v 1.15 2013/07/20 05:16:08 kefren Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2010 The NetBSD Foundation, Inc.
|
* Copyright (c) 2010 The NetBSD Foundation, Inc.
|
||||||
|
@ -38,6 +38,7 @@
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <fcntl.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <strings.h>
|
#include <strings.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
@ -77,12 +78,11 @@ ldp_peer_new(const struct in_addr * ldp_id, const struct sockaddr * padd,
|
||||||
const struct sockaddr * tradd, uint16_t holdtime, int soc)
|
const struct sockaddr * tradd, uint16_t holdtime, int soc)
|
||||||
{
|
{
|
||||||
struct ldp_peer *p;
|
struct ldp_peer *p;
|
||||||
int s = soc;
|
int s = soc, sopts;
|
||||||
struct sockaddr *connecting_sa = NULL;
|
union sockunion connecting_su;
|
||||||
struct conf_neighbour *cn;
|
struct conf_neighbour *cn;
|
||||||
|
|
||||||
if (tradd != NULL)
|
assert(tradd == NULL || tradd->sa_family == padd->sa_family);
|
||||||
assert(tradd->sa_family == padd->sa_family);
|
|
||||||
|
|
||||||
if (soc < 1) {
|
if (soc < 1) {
|
||||||
s = socket(PF_INET, SOCK_STREAM, 0);
|
s = socket(PF_INET, SOCK_STREAM, 0);
|
||||||
|
@ -91,22 +91,20 @@ ldp_peer_new(const struct in_addr * ldp_id, const struct sockaddr * padd,
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (tradd != NULL) {
|
if (tradd != NULL) {
|
||||||
connecting_sa = malloc(tradd->sa_len);
|
assert(tradd->sa_len <= sizeof(connecting_su));
|
||||||
memcpy(connecting_sa, tradd, tradd->sa_len);
|
memcpy(&connecting_su, tradd, tradd->sa_len);
|
||||||
} else {
|
} else {
|
||||||
connecting_sa = malloc(padd->sa_len);
|
assert(padd->sa_len <= sizeof(connecting_su));
|
||||||
memcpy(connecting_sa, padd, padd->sa_len);
|
memcpy(&connecting_su, padd, padd->sa_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(connecting_sa->sa_family == AF_INET ||
|
assert(connecting_su.sa.sa_family == AF_INET ||
|
||||||
connecting_sa->sa_family == AF_INET6);
|
connecting_su.sa.sa_family == AF_INET6);
|
||||||
|
|
||||||
if (connecting_sa->sa_family == AF_INET)
|
if (connecting_su.sa.sa_family == AF_INET)
|
||||||
((struct sockaddr_in*)connecting_sa)->sin_port =
|
connecting_su.sin.sin_port = htons(LDP_PORT);
|
||||||
htons(LDP_PORT);
|
|
||||||
else
|
else
|
||||||
((struct sockaddr_in6*)connecting_sa)->sin6_port =
|
connecting_su.sin6.sin6_port = htons(LDP_PORT);
|
||||||
htons(LDP_PORT);
|
|
||||||
|
|
||||||
set_ttl(s);
|
set_ttl(s);
|
||||||
}
|
}
|
||||||
|
@ -155,20 +153,23 @@ ldp_peer_new(const struct in_addr * ldp_id, const struct sockaddr * padd,
|
||||||
SLIST_INIT(&p->label_mapping_head);
|
SLIST_INIT(&p->label_mapping_head);
|
||||||
p->timeout = p->holdtime;
|
p->timeout = p->holdtime;
|
||||||
|
|
||||||
|
sopts = fcntl(p->socket, F_GETFL);
|
||||||
|
if (sopts >= 0) {
|
||||||
|
sopts |= O_NONBLOCK;
|
||||||
|
fcntl(p->socket, F_SETFL, &sopts);
|
||||||
|
}
|
||||||
|
|
||||||
/* And connect to peer */
|
/* And connect to peer */
|
||||||
if (soc < 1)
|
if (soc < 1 &&
|
||||||
if (connect(s, connecting_sa, connecting_sa->sa_len) == -1) {
|
connect(s, &connecting_su.sa, connecting_su.sa.sa_len) == -1) {
|
||||||
if (errno == EINTR) {
|
if (errno == EINTR || errno == EINPROGRESS)
|
||||||
free(connecting_sa);
|
/* We take care of this in big_loop */
|
||||||
return p; /* We take care of this in
|
return p;
|
||||||
* big_loop */
|
warnp("connect to %s failed: %s\n",
|
||||||
}
|
satos(&connecting_su.sa), strerror(errno));
|
||||||
warnp("connect to %s failed: %s\n",
|
ldp_peer_holddown(p);
|
||||||
satos(connecting_sa), strerror(errno));
|
return NULL;
|
||||||
free(connecting_sa);
|
}
|
||||||
ldp_peer_holddown(p);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
p->state = LDP_PEER_CONNECTED;
|
p->state = LDP_PEER_CONNECTED;
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
@ -176,12 +177,15 @@ ldp_peer_new(const struct in_addr * ldp_id, const struct sockaddr * padd,
|
||||||
void
|
void
|
||||||
ldp_peer_holddown(struct ldp_peer * p)
|
ldp_peer_holddown(struct ldp_peer * p)
|
||||||
{
|
{
|
||||||
if (!p)
|
|
||||||
|
if (!p || p->state == LDP_PEER_HOLDDOWN)
|
||||||
return;
|
return;
|
||||||
if (p->state == LDP_PEER_ESTABLISHED)
|
if (p->state == LDP_PEER_ESTABLISHED) {
|
||||||
|
p->state = LDP_PEER_HOLDDOWN;
|
||||||
mpls_delete_ldp_peer(p);
|
mpls_delete_ldp_peer(p);
|
||||||
p->state = LDP_PEER_HOLDDOWN;
|
} else
|
||||||
p->timeout = ldp_holddown_time;
|
p->state = LDP_PEER_HOLDDOWN;
|
||||||
|
p->timeout = p->holdtime;
|
||||||
shutdown(p->socket, SHUT_RDWR);
|
shutdown(p->socket, SHUT_RDWR);
|
||||||
ldp_peer_delete_all_mappings(p);
|
ldp_peer_delete_all_mappings(p);
|
||||||
del_all_ifaddr(p);
|
del_all_ifaddr(p);
|
||||||
|
@ -457,7 +461,7 @@ ldp_peer_delete_mapping(struct ldp_peer * p, const struct sockaddr * a,
|
||||||
struct label_mapping *lma;
|
struct label_mapping *lma;
|
||||||
|
|
||||||
if (!a)
|
if (!a)
|
||||||
return ldp_peer_delete_all_mappings(p);
|
return LDP_E_NOENT;
|
||||||
|
|
||||||
lma = ldp_peer_get_lm(p, a, prefix);
|
lma = ldp_peer_get_lm(p, a, prefix);
|
||||||
if (!lma)
|
if (!lma)
|
||||||
|
@ -486,7 +490,7 @@ ldp_peer_get_lm(const struct ldp_peer * p, const struct sockaddr * a,
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
void
|
||||||
ldp_peer_delete_all_mappings(struct ldp_peer * p)
|
ldp_peer_delete_all_mappings(struct ldp_peer * p)
|
||||||
{
|
{
|
||||||
struct label_mapping *lma;
|
struct label_mapping *lma;
|
||||||
|
@ -496,8 +500,6 @@ ldp_peer_delete_all_mappings(struct ldp_peer * p)
|
||||||
SLIST_REMOVE_HEAD(&p->label_mapping_head, mappings);
|
SLIST_REMOVE_HEAD(&p->label_mapping_head, mappings);
|
||||||
free(lma);
|
free(lma);
|
||||||
}
|
}
|
||||||
|
|
||||||
return LDP_E_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* returns a mapping and its peer */
|
/* returns a mapping and its peer */
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: ldp_peer.h,v 1.6 2013/07/11 05:55:13 kefren Exp $ */
|
/* $NetBSD: ldp_peer.h,v 1.7 2013/07/20 05:16:08 kefren Exp $ */
|
||||||
|
|
||||||
/*-
|
/*-
|
||||||
* Copyright (c) 2010 The NetBSD Foundation, Inc.
|
* Copyright (c) 2010 The NetBSD Foundation, Inc.
|
||||||
|
@ -108,7 +108,7 @@ int ldp_peer_add_mapping(struct ldp_peer *, const struct sockaddr *, int, int);
|
||||||
int ldp_peer_delete_mapping(struct ldp_peer *, const struct sockaddr *, int);
|
int ldp_peer_delete_mapping(struct ldp_peer *, const struct sockaddr *, int);
|
||||||
struct label_mapping * ldp_peer_get_lm(const struct ldp_peer *,
|
struct label_mapping * ldp_peer_get_lm(const struct ldp_peer *,
|
||||||
const struct sockaddr *, uint);
|
const struct sockaddr *, uint);
|
||||||
int ldp_peer_delete_all_mappings(struct ldp_peer *);
|
void ldp_peer_delete_all_mappings(struct ldp_peer *);
|
||||||
void ldp_peer_holddown_all(void);
|
void ldp_peer_holddown_all(void);
|
||||||
|
|
||||||
struct peer_map * ldp_test_mapping(const struct sockaddr *, int,
|
struct peer_map * ldp_test_mapping(const struct sockaddr *, int,
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: mpls_routes.c,v 1.18 2013/07/18 11:45:36 kefren Exp $ */
|
/* $NetBSD: mpls_routes.c,v 1.19 2013/07/20 05:16:08 kefren Exp $ */
|
||||||
|
|
||||||
/*-
|
/*-
|
||||||
* Copyright (c) 2010 The NetBSD Foundation, Inc.
|
* Copyright (c) 2010 The NetBSD Foundation, Inc.
|
||||||
|
@ -678,8 +678,6 @@ check_route(struct rt_msg * rg, uint rlen)
|
||||||
satos(&so_dest->sa), prefixlen);
|
satos(&so_dest->sa), prefixlen);
|
||||||
break;
|
break;
|
||||||
case RTM_DELETE:
|
case RTM_DELETE:
|
||||||
if (!so_gate)
|
|
||||||
break; /* Non-existent route XXX ?! */
|
|
||||||
/*
|
/*
|
||||||
* Send withdraw check the binding, delete the route, delete
|
* Send withdraw check the binding, delete the route, delete
|
||||||
* the binding
|
* the binding
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: socketops.c,v 1.29 2013/07/18 06:07:45 kefren Exp $ */
|
/* $NetBSD: socketops.c,v 1.30 2013/07/20 05:16:08 kefren Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2010 The NetBSD Foundation, Inc.
|
* Copyright (c) 2010 The NetBSD Foundation, Inc.
|
||||||
|
@ -932,6 +932,7 @@ the_big_loop(void)
|
||||||
p = get_ldp_peer_by_socket(pfd[i].fd);
|
p = get_ldp_peer_by_socket(pfd[i].fd);
|
||||||
if (!p)
|
if (!p)
|
||||||
continue;
|
continue;
|
||||||
|
assert(p->state == LDP_PEER_CONNECTING);
|
||||||
if (getsockopt(pfd[i].fd, SOL_SOCKET, SO_ERROR,
|
if (getsockopt(pfd[i].fd, SOL_SOCKET, SO_ERROR,
|
||||||
&sock_error, &sock_error_size) != 0 ||
|
&sock_error, &sock_error_size) != 0 ||
|
||||||
sock_error != 0) {
|
sock_error != 0) {
|
||||||
|
@ -1078,7 +1079,9 @@ recv_session_pdu(struct ldp_peer * p)
|
||||||
|
|
||||||
memset(recvspace, 0, MAX_PDU_SIZE);
|
memset(recvspace, 0, MAX_PDU_SIZE);
|
||||||
|
|
||||||
c = recv(p->socket, (void *) recvspace, MAX_PDU_SIZE, MSG_PEEK);
|
do {
|
||||||
|
c = recv(p->socket, (void *) recvspace, MAX_PDU_SIZE, MSG_PEEK);
|
||||||
|
} while (c == -1 && errno == EINTR);
|
||||||
|
|
||||||
debugp("Ready to read %d bytes\n", c);
|
debugp("Ready to read %d bytes\n", c);
|
||||||
|
|
||||||
|
@ -1097,12 +1100,12 @@ recv_session_pdu(struct ldp_peer * p)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
rpdu = (struct ldp_pdu *) recvspace;
|
rpdu = (struct ldp_pdu *) recvspace;
|
||||||
/* XXX: buggy messages may crash the whole thing */
|
do {
|
||||||
c = recv(p->socket, (void *) recvspace,
|
c = recv(p->socket, (void *) recvspace,
|
||||||
ntohs(rpdu->length) + PDU_VER_LENGTH, MSG_WAITALL);
|
ntohs(rpdu->length) + PDU_VER_LENGTH, MSG_WAITALL);
|
||||||
rpdu = (struct ldp_pdu *) recvspace;
|
} while (c == -1 && errno == EINTR);
|
||||||
|
|
||||||
/* Check if it's somehow OK... */
|
/* sanity check */
|
||||||
if (check_recv_pdu(p, rpdu, c) != 0)
|
if (check_recv_pdu(p, rpdu, c) != 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: tlv_stack.c,v 1.11 2013/07/18 11:45:36 kefren Exp $ */
|
/* $NetBSD: tlv_stack.c,v 1.12 2013/07/20 05:16:08 kefren Exp $ */
|
||||||
|
|
||||||
/*-
|
/*-
|
||||||
* Copyright (c) 2010 The NetBSD Foundation, Inc.
|
* Copyright (c) 2010 The NetBSD Foundation, Inc.
|
||||||
|
@ -209,7 +209,7 @@ withdraw_label(struct ldp_peer * p, struct fec_tlv * f)
|
||||||
case FEC_WILDCARD:
|
case FEC_WILDCARD:
|
||||||
fatalp("LDP neighbour %s: Wildcard withdraw !!!\n",
|
fatalp("LDP neighbour %s: Wildcard withdraw !!!\n",
|
||||||
satos(p->address));
|
satos(p->address));
|
||||||
ldp_peer_delete_mapping(p, NULL, 0);
|
ldp_peer_delete_all_mappings(p);
|
||||||
label_reattach_all_peer_labels(p, REATT_INET_CHANGE);
|
label_reattach_all_peer_labels(p, REATT_INET_CHANGE);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -222,7 +222,7 @@ withdraw_label(struct ldp_peer * p, struct fec_tlv * f)
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* In case of label redraw, reuse the same buffer to send label release
|
* In case of label withdraw, reuse the same buffer to send label release
|
||||||
* Simply replace type and message id
|
* Simply replace type and message id
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
|
@ -322,7 +322,8 @@ send_label_tlv_to_all(const struct sockaddr * addr, uint8_t prefixlen,
|
||||||
{
|
{
|
||||||
struct ldp_peer *p;
|
struct ldp_peer *p;
|
||||||
SLIST_FOREACH(p, &ldp_peer_head, peers)
|
SLIST_FOREACH(p, &ldp_peer_head, peers)
|
||||||
send_label_tlv(p, addr, prefixlen, label, NULL);
|
if (p->state == LDP_PEER_ESTABLISHED)
|
||||||
|
send_label_tlv(p, addr, prefixlen, label, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -400,7 +401,8 @@ send_withdraw_tlv_to_all(const struct sockaddr * addr, uint8_t prefixlen)
|
||||||
{
|
{
|
||||||
struct ldp_peer *p;
|
struct ldp_peer *p;
|
||||||
SLIST_FOREACH(p, &ldp_peer_head, peers)
|
SLIST_FOREACH(p, &ldp_peer_head, peers)
|
||||||
send_withdraw_tlv(p, addr, prefixlen);
|
if (p->state == LDP_PEER_ESTABLISHED)
|
||||||
|
send_withdraw_tlv(p, addr, prefixlen);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
|
Loading…
Reference in New Issue