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);

Reply via email to