Module Name:    src
Committed By:   kefren
Date:           Fri Jul 12 08:55:52 UTC 2013

Modified Files:
        src/usr.sbin/ldpd: fsm.c mpls_routes.c

Log Message:
correct loopback address test
correct addr add/del handling


To generate a diff of this commit:
cvs rdiff -u -r1.12 -r1.13 src/usr.sbin/ldpd/fsm.c
cvs rdiff -u -r1.13 -r1.14 src/usr.sbin/ldpd/mpls_routes.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.12 src/usr.sbin/ldpd/fsm.c:1.13
--- src/usr.sbin/ldpd/fsm.c:1.12	Thu Jul 11 05:55:13 2013
+++ src/usr.sbin/ldpd/fsm.c	Fri Jul 12 08:55:52 2013
@@ -1,4 +1,4 @@
-/* $NetBSD: fsm.c,v 1.12 2013/07/11 05:55:13 kefren Exp $ */
+/* $NetBSD: fsm.c,v 1.13 2013/07/12 08:55:52 kefren Exp $ */
 
 /*-
  * Copyright (c) 2010 The NetBSD Foundation, Inc.
@@ -186,10 +186,11 @@ build_address_list_tlv(void)
 	ia = &t->a_address;
 	for (adrcount = 0, ifb = ifa; ifb; ifb = ifb->ifa_next) {
 		if ((ifb->ifa_addr->sa_family != AF_INET) ||
-		    (!(ifb->ifa_flags & IFF_UP)) ||
-		    (ifb->ifa_flags & IFF_LOOPBACK))
+		    (!(ifb->ifa_flags & IFF_UP)))
 			continue;
 		sa = (struct sockaddr_in *) ifb->ifa_addr;
+		if (ntohl(sa->sin_addr.s_addr) >> 24 == IN_LOOPBACKNET)
+			continue;
 		memcpy(&ia[adrcount], &sa->sin_addr, sizeof(struct in_addr));
 		adrcount++;
 	}

Index: src/usr.sbin/ldpd/mpls_routes.c
diff -u src/usr.sbin/ldpd/mpls_routes.c:1.13 src/usr.sbin/ldpd/mpls_routes.c:1.14
--- src/usr.sbin/ldpd/mpls_routes.c:1.13	Thu Jul 11 18:02:03 2013
+++ src/usr.sbin/ldpd/mpls_routes.c	Fri Jul 12 08:55:52 2013
@@ -1,4 +1,4 @@
-/* $NetBSD: mpls_routes.c,v 1.13 2013/07/11 18:02:03 kefren Exp $ */
+/* $NetBSD: mpls_routes.c,v 1.14 2013/07/12 08:55:52 kefren Exp $ */
 
 /*-
  * Copyright (c) 2010 The NetBSD Foundation, Inc.
@@ -69,18 +69,19 @@ static int read_route_socket(char *, int
 void	mask_addr(union sockunion *);
 int	compare_sockunion(const union sockunion *, const union sockunion *);
 char *	mpls_ntoa(union mpls_shim);
-static int check_if_addr_updown(struct rt_msg * rg);
+static int check_if_addr_updown(struct rt_msg *, uint);
 
 extern struct sockaddr mplssockaddr;
 
 /* Many lines inspired or shamelessly stolen from sbin/route/route.c */
 
 #define NEXTADDR(u) \
-	do { l = RT_ROUNDUP(u->sa.sa_len); memcpy(cp, u, l); cp += l; } while(0);
+	do { l = RT_ROUNDUP(u->sa.sa_len); memcpy(cp, u, l); cp += l;} while(0);
 #define NEXTADDR2(u) \
 	do { l = RT_ROUNDUP(u.sa_len); memcpy(cp, &u, l); cp += l; } while(0);
 #define GETNEXT(sunion) \
-	(union sockunion *) ((char *) (sunion)  + RT_ROUNDUP((sunion)->sa.sa_len))
+	(union sockunion *) ((char *) (sunion)  + \
+	RT_ROUNDUP((sunion)->sa.sa_len))
 
 static int 
 read_route_socket(char *s, int max)
@@ -581,13 +582,16 @@ check_route(struct rt_msg * rg, uint rle
 	gate[0] = 0;
 	pref[0] = 0;
 
-	if (rlen <= sizeof(struct rt_msghdr) ||
-	    rg->m_rtm.rtm_version != RTM_VERSION)
+	if (rlen < 3 || rg->m_rtm.rtm_version != RTM_VERSION)
 		return LDP_E_ROUTE_ERROR;
 
 	if (rg->m_rtm.rtm_type == RTM_NEWADDR ||
 	    rg->m_rtm.rtm_type == RTM_DELADDR)
-		return check_if_addr_updown(rg);
+		return check_if_addr_updown(rg, rlen);
+
+	if (rlen < sizeof(struct rt_msghdr))
+		return LDP_E_ROUTE_ERROR;
+
 	if (rg->m_rtm.rtm_pid == getpid() ||
 	    ((rg->m_rtm.rtm_flags & RTF_DONE) == 0))
 		return LDP_E_OK;
@@ -719,6 +723,9 @@ check_route(struct rt_msg * rg, uint rle
 	case RTM_LOSING:
 		strlcpy(oper, "losing", 20);
 		break;
+	case RTM_REDIRECT:
+		strlcpy(oper, "redirect", 20);
+		break;
 	case RTM_NEWADDR:
 		strlcpy(oper, "new address", 20);
 		break;
@@ -726,7 +733,7 @@ check_route(struct rt_msg * rg, uint rle
 		strlcpy(oper, "del address", 20);
 		break;
 	default:
-		snprintf(oper, 50, "unknown 0x%X operation",
+		snprintf(oper, sizeof(oper), "unknown 0x%X operation",
 		    rg->m_rtm.rtm_type);
 	}
 
@@ -742,25 +749,29 @@ check_route(struct rt_msg * rg, uint rle
  * Checks NEWADDR and DELADDR messages and sends announcements accordingly
  */
 static int
-check_if_addr_updown(struct rt_msg * rg)
+check_if_addr_updown(struct rt_msg * rg, uint rlen)
 {
 	union sockunion *ifa, *netmask;
 	struct ldp_peer *p;
 	struct address_list_tlv al_tlv;
+	struct ifa_msghdr *msghdr = (struct ifa_msghdr *)&rg->m_rtm;
 
-	if ((rg->m_rtm.rtm_addrs & RTA_NETMASK) == 0 ||
-	    (rg->m_rtm.rtm_addrs & RTA_IFA) == 0)
+	if (rlen < sizeof(struct ifa_msghdr) ||
+	    (msghdr->ifam_addrs & RTA_NETMASK) == 0 ||
+	    (msghdr->ifam_addrs & RTA_IFA) == 0)
 		return LDP_E_ROUTE_ERROR;
 
-	ifa = netmask = (union sockunion *) rg->m_space;
+	/* we should have RTA_NETMASK, RTA_IFP, RTA_IFA and RTA_BRD */
+	ifa = netmask = (union sockunion *)(msghdr + 1);
 	if (netmask->sa.sa_family != AF_INET)
 		return LDP_E_OK;
 
-	if (rg->m_rtm.rtm_addrs & RTA_IFP)
-		ifa = GETNEXT(netmask);
+	if (msghdr->ifam_addrs & RTA_IFP)
+		ifa = GETNEXT(ifa);
 	ifa = GETNEXT(ifa);
 
-	if (ifa->sa.sa_family != AF_INET)
+	if (ifa->sa.sa_family != AF_INET ||
+	    ntohl(ifa->sin.sin_addr.s_addr) >> 24 == IN_LOOPBACKNET)
 		return LDP_E_OK;
 
 	memset(&al_tlv, 0, sizeof(al_tlv));

Reply via email to