Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 14 Jun 2011 07:20:16 +0000 (UTC)
From:      "Andrey V. Elsukov" <ae@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r223073 - head/sys/netinet/ipfw
Message-ID:  <201106140720.p5E7KGAu018390@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: ae
Date: Tue Jun 14 07:20:16 2011
New Revision: 223073
URL: http://svn.freebsd.org/changeset/base/223073

Log:
  Add IPv6 support to the ipfw uid/gid check. Pass an ip_fw_args structure
  to the check_uidgid() function, since it contains all needed arguments
  and also pointer to mbuf and now it is possible use in_pcblookup_mbuf()
  function.
  
  Since i can not test it for the non-FreeBSD case, i keep this ifdef
  unchanged.
  
  Tested by:	Alexander V. Chernikov
  MFC after:	3 weeks

Modified:
  head/sys/netinet/ipfw/ip_fw2.c

Modified: head/sys/netinet/ipfw/ip_fw2.c
==============================================================================
--- head/sys/netinet/ipfw/ip_fw2.c	Tue Jun 14 06:45:48 2011	(r223072)
+++ head/sys/netinet/ipfw/ip_fw2.c	Tue Jun 14 07:20:16 2011	(r223073)
@@ -84,6 +84,7 @@ __FBSDID("$FreeBSD$");
 #include <netinet/ip6.h>
 #include <netinet/icmp6.h>
 #ifdef INET6
+#include <netinet6/in6_pcb.h>
 #include <netinet6/scope6_var.h>
 #include <netinet6/ip6_var.h>
 #endif
@@ -646,21 +647,27 @@ send_reject(struct ip_fw_args *args, int
  * we tried and failed, or any other value if successful.
  */
 static int
-check_uidgid(ipfw_insn_u32 *insn, int proto, struct ifnet *oif,
-    struct in_addr dst_ip, u_int16_t dst_port, struct in_addr src_ip,
-    u_int16_t src_port, int *ugid_lookupp,
-    struct ucred **uc, struct inpcb *inp)
+check_uidgid(ipfw_insn_u32 *insn, struct ip_fw_args *args, int *ugid_lookupp,
+    struct ucred **uc)
 {
 #ifndef __FreeBSD__
+	/* XXX */
 	return cred_check(insn, proto, oif,
 	    dst_ip, dst_port, src_ip, src_port,
 	    (struct bsd_ucred *)uc, ugid_lookupp, ((struct mbuf *)inp)->m_skb);
 #else  /* FreeBSD */
+	struct in_addr src_ip, dst_ip;
 	struct inpcbinfo *pi;
+	struct ipfw_flow_id *id;
+	struct inpcb *pcb, *inp;
+	struct ifnet *oif;
 	int lookupflags;
-	struct inpcb *pcb;
 	int match;
 
+	id = &args->f_id;
+	inp = args->inp;
+	oif = args->oif;
+
 	/*
 	 * Check to see if the UDP or TCP stack supplied us with
 	 * the PCB. If so, rather then holding a lock and looking
@@ -681,10 +688,10 @@ check_uidgid(ipfw_insn_u32 *insn, int pr
 	 */
 	if (*ugid_lookupp == -1)
 		return (0);
-	if (proto == IPPROTO_TCP) {
+	if (id->proto == IPPROTO_TCP) {
 		lookupflags = 0;
 		pi = &V_tcbinfo;
-	} else if (proto == IPPROTO_UDP) {
+	} else if (id->proto == IPPROTO_UDP) {
 		lookupflags = INPLOOKUP_WILDCARD;
 		pi = &V_udbinfo;
 	} else
@@ -692,19 +699,36 @@ check_uidgid(ipfw_insn_u32 *insn, int pr
 	lookupflags |= INPLOOKUP_RLOCKPCB;
 	match = 0;
 	if (*ugid_lookupp == 0) {
-		/*
-		 * XXXRW: If we had the mbuf here, could use
-		 * in_pcblookup_mbuf().
-		 */
-		pcb =  (oif) ?
-			in_pcblookup(pi,
-				dst_ip, htons(dst_port),
-				src_ip, htons(src_port),
-				lookupflags, oif) :
-			in_pcblookup(pi,
-				src_ip, htons(src_port),
-				dst_ip, htons(dst_port),
-				lookupflags, NULL);
+		if (id->addr_type == 6) {
+#ifdef INET6
+			if (oif == NULL)
+				pcb = in6_pcblookup_mbuf(pi,
+				    &id->src_ip6, htons(id->src_port),
+				    &id->dst_ip6, htons(id->dst_port),
+				    lookupflags, oif, args->m);
+			else
+				pcb = in6_pcblookup_mbuf(pi,
+				    &id->dst_ip6, htons(id->dst_port),
+				    &id->src_ip6, htons(id->src_port),
+				    lookupflags, oif, args->m);
+#else
+			*ugid_lookupp = -1;
+			return (0);
+#endif
+		} else {
+			src_ip.s_addr = htonl(id->src_ip);
+			dst_ip.s_addr = htonl(id->dst_ip);
+			if (oif == NULL)
+				pcb = in_pcblookup_mbuf(pi,
+				    src_ip, htons(id->src_port),
+				    dst_ip, htons(id->dst_port),
+				    lookupflags, oif, args->m);
+			else
+				pcb = in_pcblookup_mbuf(pi,
+				    dst_ip, htons(id->dst_port),
+				    src_ip, htons(id->src_port),
+				    lookupflags, oif, args->m);
+		}
 		if (pcb != NULL) {
 			INP_RLOCK_ASSERT(pcb);
 			*uc = crhold(pcb->inp_cred);
@@ -719,14 +743,14 @@ check_uidgid(ipfw_insn_u32 *insn, int pr
 			*ugid_lookupp = -1;
 			return (0);
 		}
-	} 
+	}
 	if (insn->o.opcode == O_UID)
 		match = ((*uc)->cr_uid == (uid_t)insn->d[0]);
 	else if (insn->o.opcode == O_GID)
 		match = groupmember((gid_t)insn->d[0], *uc);
 	else if (insn->o.opcode == O_JAIL)
 		match = ((*uc)->cr_prison->pr_id == (int)insn->d[0]);
-	return match;
+	return (match);
 #endif /* __FreeBSD__ */
 }
 
@@ -1264,22 +1288,17 @@ do {								\
 				 * as this ensures that we have a
 				 * packet with the ports info.
 				 */
-				if (offset!=0)
-					break;
-				if (is_ipv6) /* XXX to be fixed later */
+				if (offset != 0)
 					break;
 				if (proto == IPPROTO_TCP ||
 				    proto == IPPROTO_UDP)
 					match = check_uidgid(
 						    (ipfw_insn_u32 *)cmd,
-						    proto, oif,
-						    dst_ip, dst_port,
-						    src_ip, src_port, &ucred_lookup,
+						    args, &ucred_lookup,
 #ifdef __FreeBSD__
-						    &ucred_cache, args->inp);
+						    &ucred_cache);
 #else
-						    (void *)&ucred_cache,
-						    (struct inpcb *)args->m);
+						    (void *)&ucred_cache);
 #endif
 				break;
 
@@ -1394,18 +1413,15 @@ do {								\
 					else if (v == 4 || v == 5) {
 					    check_uidgid(
 						(ipfw_insn_u32 *)cmd,
-						proto, oif,
-						dst_ip, dst_port,
-						src_ip, src_port, &ucred_lookup,
+						args, &ucred_lookup,
 #ifdef __FreeBSD__
-						&ucred_cache, args->inp);
+						&ucred_cache);
 					    if (v == 4 /* O_UID */)
 						key = ucred_cache->cr_uid;
 					    else if (v == 5 /* O_JAIL */)
 						key = ucred_cache->cr_prison->pr_id;
 #else /* !__FreeBSD__ */
-						(void *)&ucred_cache,
-						(struct inpcb *)args->m);
+						(void *)&ucred_cache);
 					    if (v ==4 /* O_UID */)
 						key = ucred_cache.uid;
 					    else if (v == 5 /* O_JAIL */)



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201106140720.p5E7KGAu018390>