summaryrefslogtreecommitdiff
path: root/usr.sbin/ldpd
diff options
context:
space:
mode:
authorkefren <kefren@NetBSD.org>2013-02-05 13:02:33 +0000
committerkefren <kefren@NetBSD.org>2013-02-05 13:02:33 +0000
commit00a254a70697c471ee4cea8309f50d5e8550f33e (patch)
tree2210dce6843bbdd444954c08de5482ba7db2f558 /usr.sbin/ldpd
parente041116831c947aebd361da99c8ac158d773efd8 (diff)
Stop confusing peer hello source with peer transport address
Diffstat (limited to 'usr.sbin/ldpd')
-rw-r--r--usr.sbin/ldpd/fsm.c95
1 files changed, 47 insertions, 48 deletions
diff --git a/usr.sbin/ldpd/fsm.c b/usr.sbin/ldpd/fsm.c
index 2a43912153a..5748a1fb032 100644
--- a/usr.sbin/ldpd/fsm.c
+++ b/usr.sbin/ldpd/fsm.c
@@ -1,4 +1,4 @@
-/* $NetBSD: fsm.c,v 1.9 2013/02/03 19:41:59 kefren Exp $ */
+/* $NetBSD: fsm.c,v 1.10 2013/02/05 13:02:33 kefren Exp $ */
/*-
* Copyright (c) 2010 The NetBSD Foundation, Inc.
@@ -56,7 +56,8 @@ run_ldp_hello(struct ldp_pdu * pduid, struct hello_tlv * ht,
{
struct ldp_peer *peer = NULL;
struct transport_address_tlv *trtlv;
- struct hello_info *hi;
+ struct hello_info *hi = NULL;
+ union sockunion traddr;
if ((!pduid) || (!ht))
return;
@@ -65,32 +66,58 @@ run_ldp_hello(struct ldp_pdu * pduid, struct hello_tlv * ht,
debugp("Hello: Type: 0x%.4X Length: %.2d ID: %.8X\n", ht->type,
ht->length, ht->messageid);
+ if (ht->length <= 4) /* Common hello parameters */
+ return;
+ ht->ch.type = ntohs(ht->ch.type);
+ ht->ch.length = ntohs(ht->ch.length);
+ ht->ch.holdtime = ntohs(ht->ch.holdtime);
+ ht->ch.res = ntohs(ht->ch.res);
+ debugp("Common hello Type: 0x%.4X Length: %.2d R:%d T:%d"
+ " Hold time: %d\n", ht->ch.type, ht->ch.length,
+ ht->ch.tr / 2, ht->ch.tr % 2, ht->ch.holdtime);
+
+ memset(&traddr, 0, sizeof(traddr));
+ /* Check transport TLV */
+ if (pduid->length - PDU_PAYLOAD_LENGTH -
+ sizeof(struct hello_tlv) >= 8) {
+ trtlv = (struct transport_address_tlv *)(ht + 1);
+ if (trtlv->type == htons(TLV_IPV4_TRANSPORT)) {
+ traddr.sin.sin_family = AF_INET;
+ traddr.sin.sin_len = sizeof(struct sockaddr_in);
+ memcpy(&traddr.sin.sin_addr,
+ &trtlv->address, sizeof(struct in_addr));
+ } else if (trtlv->type == htons(TLV_IPV6_TRANSPORT)) {
+ traddr.sin6.sin6_family = AF_INET6;
+ traddr.sin6.sin6_len = sizeof(struct sockaddr_in6);
+ memcpy(&traddr.sin6.sin6_addr,
+ &trtlv->address, sizeof(struct in6_addr));
+ } else
+ warnp("Unknown AF %x for transport address\n",
+ ntohs(trtlv->type));
+ } else {
+ /* Use LDP ID as transport address */
+ traddr.sin.sin_family = AF_INET;
+ traddr.sin.sin_len = sizeof(struct sockaddr_in);
+ memcpy(&traddr.sin.sin_addr,
+ &pduid->ldp_id, sizeof(struct in_addr));
+ }
/* Add it to hello list or just update timer */
SLIST_FOREACH(hi, &hello_info_head, infos)
- if (hi->ldp_id.s_addr == pduid->ldp_id.s_addr)
+ if (hi->ldp_id.s_addr == pduid->ldp_id.s_addr &&
+ sockaddr_cmp(&hi->transport_address.sa, &traddr.sa) == 0)
break;
if (hi == NULL) {
- hi = malloc(sizeof(*hi));
+ hi = calloc(1, sizeof(*hi));
if (!hi) {
fatalp("Cannot alloc a hello info structure");
return;
}
hi->ldp_id.s_addr = pduid->ldp_id.s_addr;
- hi->transport_address.sa.sa_family = 0;
+ memcpy(&hi->transport_address, &traddr, traddr.sa.sa_len);
SLIST_INSERT_HEAD(&hello_info_head, hi, infos);
- } else
- /* Just update timer */
- hi->keepalive = LDP_HELLO_KEEP;
+ }
- if (ht->length <= 4) /* Common hello parameters */
- return;
- ht->ch.type = ntohs(ht->ch.type);
- ht->ch.length = ntohs(ht->ch.length);
- ht->ch.holdtime = ntohs(ht->ch.holdtime);
- ht->ch.res = ntohs(ht->ch.res);
- debugp("Common hello Type: 0x%.4X Length: %.2d R:%d T:%d"
- " Hold time: %d\n", ht->ch.type, ht->ch.length,
- ht->ch.tr / 2, ht->ch.tr % 2, ht->ch.holdtime);
+ /* Update expire timer */
if (ht->ch.holdtime != 0)
hi->keepalive = ht->ch.holdtime;
else {
@@ -99,44 +126,16 @@ run_ldp_hello(struct ldp_pdu * pduid, struct hello_tlv * ht,
else
hi->keepalive = LDP_THELLO_KEEP;
}
+
if (!get_ldp_peer_by_id(&pduid->ldp_id)) {
- /* Check transport TLV */
- if (pduid->length - PDU_PAYLOAD_LENGTH -
- sizeof(struct hello_tlv) >= 8) {
- trtlv = (struct transport_address_tlv *)(ht + 1);
- if (trtlv->type == htons(TLV_IPV4_TRANSPORT)) {
- hi->transport_address.sin.sin_family = AF_INET;
- hi->transport_address.sin.sin_len =
- sizeof(struct sockaddr_in);
- memcpy(&hi->transport_address.sin.sin_addr,
- &trtlv->address, sizeof(struct in_addr));
- } else if (trtlv->type == htons(TLV_IPV6_TRANSPORT)) {
- hi->transport_address.sin6.sin6_family =
- AF_INET6;
- hi->transport_address.sin6.sin6_len =
- sizeof(struct sockaddr_in6);
- memcpy(&hi->transport_address.sin6.sin6_addr,
- &trtlv->address, sizeof(struct in6_addr));
- } else
- warnp("Unknown AF %x for transport address\n",
- ntohs(trtlv->type));
- } else {
- trtlv = NULL;
- hi->transport_address.sin.sin_family = AF_INET;
- hi->transport_address.sin.sin_len =
- sizeof(struct sockaddr_in);
- memcpy(&hi->transport_address.sin.sin_addr,
- &pduid->ldp_id, sizeof(struct in_addr));
- }
/*
* RFC 5036 2.5.2: If A1 > A2, LSR1 plays the active role;
* otherwise it is passive.
*/
- /* XXX TODO: check for IPv6 too */
if (may_connect == true &&
- hi->transport_address.sa.sa_family == AF_INET &&
+ (hi->transport_address.sa.sa_family == AF_INET &&
ntohl(hi->transport_address.sin.sin_addr.s_addr) <
- ntohl(ladd->s_addr)) {
+ ntohl(ladd->s_addr))) {
peer = ldp_peer_new(&pduid->ldp_id, padd,
&hi->transport_address.sa,
ht->ch.holdtime, 0);