Module Name: src
Committed By: kefren
Date: Tue Feb 5 13:02:33 UTC 2013
Modified Files:
src/usr.sbin/ldpd: fsm.c
Log Message:
Stop confusing peer hello source with peer transport address
To generate a diff of this commit:
cvs rdiff -u -r1.9 -r1.10 src/usr.sbin/ldpd/fsm.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/usr.sbin/ldpd/fsm.c
diff -u src/usr.sbin/ldpd/fsm.c:1.9 src/usr.sbin/ldpd/fsm.c:1.10
--- src/usr.sbin/ldpd/fsm.c:1.9 Sun Feb 3 19:41:59 2013
+++ src/usr.sbin/ldpd/fsm.c Tue Feb 5 13:02:33 2013
@@ -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, st
{
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, st
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, st
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);