Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 15 Jun 2008 14:10:27 GMT
From:      Gleb Kurtsou <gk@FreeBSD.org>
To:        Perforce Change Reviews <perforce@FreeBSD.org>
Subject:   PERFORCE change 143510 for review
Message-ID:  <200806151410.m5FEAR46025067@repoman.freebsd.org>

index | next in thread | raw e-mail

http://perforce.freebsd.org/chv.cgi?CH=143510

Change 143510 by gk@gk_h1 on 2008/06/15 14:10:06

	support stateful filtering by layer2 addresses.
	check only layer2 addresses, that were specified in rule created state.
	allow packet if it contains no layer2 addresses tag in stateful filter
	but we excpect to have one.  problem is that tagging is performed only for
	incomming packet on ethernet interfaces and for outgoing packets on if_bridge.

Affected files ...

.. //depot/projects/soc2008/gk_l2filter/sys-netinet/ip_fw.h#8 edit
.. //depot/projects/soc2008/gk_l2filter/sys-netinet/ip_fw2.c#9 edit

Differences ...

==== //depot/projects/soc2008/gk_l2filter/sys-netinet/ip_fw.h#8 (text+ko) ====

@@ -268,7 +268,7 @@
 #define IP_FW_EA_CHECK		0x02
 #define IP_FW_EA_MULTICAST	0x04
 
-typedef struct _ip_fw_ether_addr {
+typedef struct _ipfw_ether_addr {
 	u_char octet[6];
 	u_int16_t flags;
 } ipfw_ether_addr;
@@ -485,6 +485,8 @@
 	struct in6_addr src_ip6;
 	u_int32_t	flow_id6;
 	u_int32_t	frag_id6;
+	ipfw_ether_addr src_ether;
+	ipfw_ether_addr dst_ether;
 };
 
 #define IS_IP6_FLOW_ID(id)	((id)->addr_type == 6)

==== //depot/projects/soc2008/gk_l2filter/sys-netinet/ip_fw2.c#9 (text+ko) ====

@@ -166,7 +166,13 @@
 #define EA_CMP(a) (*((u_int64_t*)(a)) & *((u_int64_t*)&mask))
 	return (EA_CMP(want) == EA_CMP(ea));
 #undef EA_CMP
+}
 
+static __inline int ether_addr_allow_dyn(ipfw_ether_addr *want, ipfw_ether_addr *a)
+{
+	if ((a->flags & IP_FW_EA_INIT) == 0)
+		return (1);
+	return (ether_addr_allow(want, (struct ether_addr *)a->octet));
 }
 
 struct table_entry {
@@ -1226,7 +1232,23 @@
 	if (q == NULL)
 		goto done; /* q = NULL, not found */
 
-	if ( prev != NULL) { /* found and not in front */
+	/*
+	 * Only check {src,dst}_ether if it was specified in rule and packet
+	 * mbuf has mtag_ether_header.
+	 */
+	if (dir == MATCH_NONE ||
+			!ether_addr_allow_dyn(&q->id.src_ether,
+			(dir == MATCH_FORWARD ? &pkt->src_ether : &pkt->dst_ether)) ||
+			!ether_addr_allow_dyn(&q->id.dst_ether,
+			(dir == MATCH_FORWARD ? &pkt->dst_ether : &pkt->src_ether))) {
+		printf("XXX IPFW DYN RULE: dropped by mac: %6D -> %6D\n",
+				&pkt->src_ether.octet, ":", &pkt->dst_ether.octet, ":");
+		q = NULL;
+		dir = MATCH_NONE;
+		goto done;
+	}
+
+	if (prev != NULL) { /* found and not in front */
 		prev->next = q->next;
 		q->next = ipfw_dyn_v[i];
 		ipfw_dyn_v[i] = q;
@@ -2247,8 +2269,18 @@
 	/*
 	 * if we have an ether header,
 	 */
-	if (args->eh)
+	if (args->eh) {
 		etype = ntohs(args->eh->ether_type);
+		memcpy(args->f_id.src_ether.octet, args->eh->ether_shost, 
+				ETHER_ADDR_LEN);
+		args->f_id.src_ether.flags = IP_FW_EA_INIT;
+		memcpy(args->f_id.dst_ether.octet, args->eh->ether_dhost, 
+				ETHER_ADDR_LEN);
+		args->f_id.dst_ether.flags = IP_FW_EA_INIT;
+	} else {
+		args->f_id.src_ether.flags = 0;
+		args->f_id.dst_ether.flags = 0;
+	}
 
 	/* Identify IP packets and fill up variables. */
 	if (pktlen >= sizeof(struct ip6_hdr) &&
@@ -2611,6 +2643,13 @@
 							(cmd->opcode == O_ETHER_SRC ?
 							args->eh->ether_shost :
 							args->eh->ether_dhost));
+					if (match) {
+						/* use address to create dynamic rule */
+						ipfw_ether_addr *a = (cmd->opcode == O_ETHER_SRC ?
+								&args->f_id.src_ether :
+								&args->f_id.dst_ether);
+						*a = *want;
+					}
 				}
 				break;
 


help

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