Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 30 Mar 2009 12:26:19 +0000 (UTC)
From:      Paolo Pisati <piso@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-user@freebsd.org
Subject:   svn commit: r190555 - in user/piso: sbin/ipfw sys/netinet
Message-ID:  <200903301226.n2UCQJ5t066608@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: piso
Date: Mon Mar 30 12:26:19 2009
New Revision: 190555
URL: http://svn.freebsd.org/changeset/base/190555

Log:
  Implement ipfw reass action.

Modified:
  user/piso/sbin/ipfw/ipfw2.c
  user/piso/sbin/ipfw/ipfw2.h
  user/piso/sys/netinet/ip_fw.h
  user/piso/sys/netinet/ip_fw2.c

Modified: user/piso/sbin/ipfw/ipfw2.c
==============================================================================
--- user/piso/sbin/ipfw/ipfw2.c	Mon Mar 30 12:18:24 2009	(r190554)
+++ user/piso/sbin/ipfw/ipfw2.c	Mon Mar 30 12:26:19 2009	(r190555)
@@ -1089,6 +1089,10 @@ show_ipfw(struct ip_fw *rule, int pcwidt
 		case O_SETFIB:
 			PRINT_UINT_ARG("setfib ", cmd->arg1);
  			break;
+
+		case O_REASS:
+			printf("reass");
+			break;
 			
 		default:
 			printf("** unrecognized action %d len %d ",
@@ -2781,6 +2785,10 @@ chkarg:	
  		ac--; av++;
  		break;
 	    }
+
+	case TOK_REASS:
+		action->opcode = O_REASS;
+		break;
 		
 	default:
 		errx(EX_DATAERR, "invalid action %s\n", av[-1]);

Modified: user/piso/sbin/ipfw/ipfw2.h
==============================================================================
--- user/piso/sbin/ipfw/ipfw2.h	Mon Mar 30 12:18:24 2009	(r190554)
+++ user/piso/sbin/ipfw/ipfw2.h	Mon Mar 30 12:26:19 2009	(r190555)
@@ -95,6 +95,7 @@ enum tokens {
 	TOK_UNREACH,
 	TOK_CHECKSTATE,
 	TOK_NAT,
+	TOK_REASS,
 
 	TOK_ALTQ,
 	TOK_LOG,

Modified: user/piso/sys/netinet/ip_fw.h
==============================================================================
--- user/piso/sys/netinet/ip_fw.h	Mon Mar 30 12:18:24 2009	(r190554)
+++ user/piso/sys/netinet/ip_fw.h	Mon Mar 30 12:26:19 2009	(r190555)
@@ -139,7 +139,8 @@ enum ipfw_opcodes {		/* arguments (4 byt
 	O_FORWARD_IP,		/* fwd sockaddr			*/
 	O_FORWARD_MAC,		/* fwd mac			*/
 	O_NAT,                  /* nope                         */
-
+	O_REASS,                /* none                         */
+	
 	/*
 	 * More opcodes.
 	 */

Modified: user/piso/sys/netinet/ip_fw2.c
==============================================================================
--- user/piso/sys/netinet/ip_fw2.c	Mon Mar 30 12:18:24 2009	(r190554)
+++ user/piso/sys/netinet/ip_fw2.c	Mon Mar 30 12:26:19 2009	(r190555)
@@ -898,6 +898,9 @@ ipfw_log(struct ip_fw *f, u_int hlen, st
 		case O_NAT:
 			action = "Nat";
  			break;
+		case O_REASS:
+			action = "Reass";
+			break;
 		default:
 			action = "UNKNOWN";
 			break;
@@ -3375,6 +3378,61 @@ check_body:
 				goto done;
 			}
 
+			case O_REASS: {
+				int ip_off;
+
+				f->pcnt++;
+				f->bcnt += pktlen;
+				ip_off = (args->eh != NULL) ? ntohs(ip->ip_off) : ip->ip_off;
+				if (ip_off & (IP_MF | IP_OFFMASK)) {
+					struct mbuf *reass;
+
+					/* 
+					 * ip_reass() expects len & off in host
+					 * byte order: fix them in case we come
+					 * from layer2.
+					 */
+					if (args->eh != NULL) {
+						ip->ip_len = ntohs(ip->ip_len);
+						ip->ip_off = ntohs(ip->ip_off);
+					}
+
+					reass = ip_reass(m);
+					
+					/*
+					 * IP header checksum fixup after 
+					 * reassembly and leave header
+					 * in network byte order.
+					 */
+					if (reass != NULL) {
+						int hlen;
+					
+						m = reass;	
+						ip = mtod(m, struct ip *);
+						hlen = ip->ip_hl << 2;
+						/* revert len & off for layer2 pkts */
+						if (args->eh != NULL) {
+							ip->ip_len = htons(ip->ip_len);
+							/* XXX ip_off == 0 ?!?!? */
+							ip->ip_off = htons(ip->ip_off);
+						}
+						ip->ip_sum = 0;
+						if (hlen == sizeof(struct ip))
+							ip->ip_sum = in_cksum_hdr(ip);
+						else
+							ip->ip_sum = in_cksum(m, hlen);
+						IPFW_RUNLOCK(chain);
+						/* XXX race */
+						goto reinit;
+					} else {
+						/* XXX mbuf double free? */
+						retval = IP_FW_DENY;
+						goto done;
+					}
+				}
+				goto next_rule;
+			}
+
 			default:
 				panic("-- unknown opcode %d\n", cmd->opcode);
 			} /* end of switch() on opcodes */
@@ -4024,6 +4082,7 @@ check_ipfw_struct(struct ip_fw *rule, in
 		case O_UNREACH6:
 #endif
 		case O_SKIPTO:
+		case O_REASS:
 check_size:
 			if (cmdlen != F_INSN_SIZE(ipfw_insn))
 				goto bad_size;



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