Module Name:    src
Committed By:   kefren
Date:           Sat Jul 27 14:35:41 UTC 2013

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

Log Message:
check route messages sizes more carefully
cache pid
treat every message at a time, even if there are more messages to read
interpret also cloning routes

The latter two should fix the ldp_regen test


To generate a diff of this commit:
cvs rdiff -u -r1.20 -r1.21 src/usr.sbin/ldpd/mpls_routes.c
cvs rdiff -u -r1.30 -r1.31 src/usr.sbin/ldpd/socketops.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/mpls_routes.c
diff -u src/usr.sbin/ldpd/mpls_routes.c:1.20 src/usr.sbin/ldpd/mpls_routes.c:1.21
--- src/usr.sbin/ldpd/mpls_routes.c:1.20	Wed Jul 24 09:05:53 2013
+++ src/usr.sbin/ldpd/mpls_routes.c	Sat Jul 27 14:35:41 2013
@@ -1,4 +1,4 @@
-/* $NetBSD: mpls_routes.c,v 1.20 2013/07/24 09:05:53 kefren Exp $ */
+/* $NetBSD: mpls_routes.c,v 1.21 2013/07/27 14:35:41 kefren Exp $ */
 
 /*-
  * Copyright (c) 2010 The NetBSD Foundation, Inc.
@@ -62,6 +62,7 @@ int             rt_seq = 200;
 int		dont_catch = 0;
 extern int	no_default_route;
 extern int	debug_f, warn_f;
+static int	my_pid = 0;
 
 struct rt_msg   replay_rt[REPLAY_MAX];
 int             replay_index = 0;
@@ -588,7 +589,8 @@ check_route(struct rt_msg * rg, uint rle
 	gate[0] = 0;
 	pref[0] = 0;
 
-	if (rlen < 3 || rg->m_rtm.rtm_version != RTM_VERSION)
+	if (rlen <= offsetof(struct rt_msghdr, rtm_type) ||
+	    rg->m_rtm.rtm_version != RTM_VERSION)
 		return LDP_E_ROUTE_ERROR;
 
 	if (rg->m_rtm.rtm_type == RTM_NEWADDR ||
@@ -598,13 +600,23 @@ check_route(struct rt_msg * rg, uint rle
 	size_cp = sizeof(struct rt_msghdr);
 	CHECK_MINSA;
 
-	if (rg->m_rtm.rtm_pid == getpid() ||
-	    ((rg->m_rtm.rtm_flags & RTF_DONE) == 0))
+	if (my_pid == 0)
+		my_pid = getpid();
+	assert(my_pid != 0);
+
+	if (rg->m_rtm.rtm_pid == my_pid ||
+	    (rg->m_rtm.rtm_pid != 0 && (rg->m_rtm.rtm_flags & RTF_DONE) == 0) ||
+	    (rg->m_rtm.rtm_type != RTM_ADD &&
+	     rg->m_rtm.rtm_type != RTM_DELETE &&
+	     rg->m_rtm.rtm_type != RTM_CHANGE))
 		return LDP_E_OK;
 
 	debugp("Check route triggered by PID: %d\n", rg->m_rtm.rtm_pid);
 
-	so_dest = (union sockunion *) rg->m_space;
+	if (rg->m_rtm.rtm_addrs & RTA_DST)
+		so_dest = (union sockunion *) rg->m_space;
+	else
+		return LDP_E_ROUTE_ERROR;
 
 	if (so_dest->sa.sa_family != AF_INET)
 		return LDP_E_OK;/* We don't care about non-IP changes */
@@ -613,8 +625,9 @@ check_route(struct rt_msg * rg, uint rle
 
 	if (rg->m_rtm.rtm_addrs & RTA_GATEWAY) {
 		GETNEXT(so_gate, so_dest);
-		if ((so_gate->sa.sa_family != AF_INET) &&
-		    (so_gate->sa.sa_family != AF_MPLS))
+		if ((rg->m_rtm.rtm_flags & RTF_CLONING) == 0 &&
+		    so_gate->sa.sa_family != AF_INET &&
+		    so_gate->sa.sa_family != AF_MPLS)
 			return LDP_E_OK;
 	}
 	if (rg->m_rtm.rtm_addrs & RTA_NETMASK) {
@@ -636,6 +649,9 @@ check_route(struct rt_msg * rg, uint rle
 	so_pref->sa.sa_family = AF_INET;
 	so_pref->sa.sa_len = sizeof(struct sockaddr_in);
 
+	if (rg->m_rtm.rtm_flags & RTF_CLONING)
+		so_gate = NULL;
+
 	switch (rg->m_rtm.rtm_type) {
 	case RTM_CHANGE:
 		lab = label_get(so_dest, so_pref);

Index: src/usr.sbin/ldpd/socketops.c
diff -u src/usr.sbin/ldpd/socketops.c:1.30 src/usr.sbin/ldpd/socketops.c:1.31
--- src/usr.sbin/ldpd/socketops.c:1.30	Sat Jul 20 05:16:08 2013
+++ src/usr.sbin/ldpd/socketops.c	Sat Jul 27 14:35:41 2013
@@ -1,4 +1,4 @@
-/* $NetBSD: socketops.c,v 1.30 2013/07/20 05:16:08 kefren Exp $ */
+/* $NetBSD: socketops.c,v 1.31 2013/07/27 14:35:41 kefren Exp $ */
 
 /*
  * Copyright (c) 2010 The NetBSD Foundation, Inc.
@@ -903,10 +903,15 @@ the_big_loop(void)
 					new_peer_connection();
 				else if (pfd[i].fd == route_socket) {
 					struct rt_msg xbuf;
-					int l;
+					int l, rtmlen = sizeof(xbuf);
+					/* Read at least rtm_msglen */
+					l = recv(route_socket, &xbuf,
+					  sizeof(u_short), MSG_PEEK);
+					if (l == sizeof(u_short))
+						rtmlen = xbuf.m_rtm.rtm_msglen;
 					do {
-						l = read(route_socket, &xbuf,
-						    sizeof(xbuf));
+						l = recv(route_socket, &xbuf,
+						    rtmlen, MSG_WAITALL);
 					} while ((l == -1) && (errno == EINTR));
 
 					if (l == -1)

Reply via email to