PERFORCE change 143510 for review

Gleb Kurtsou gk at FreeBSD.org
Sun Jun 15 14:10:28 UTC 2008


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

Change 143510 by gk at 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;
 


More information about the p4-projects mailing list