From owner-p4-projects@FreeBSD.ORG Sun Jun 15 14:10:28 2008 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 3725A1065673; Sun, 15 Jun 2008 14:10:28 +0000 (UTC) Delivered-To: perforce@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id D5B8D106566C for ; Sun, 15 Jun 2008 14:10:27 +0000 (UTC) (envelope-from gk@FreeBSD.org) Received: from repoman.freebsd.org (repoman.freebsd.org [IPv6:2001:4f8:fff6::29]) by mx1.freebsd.org (Postfix) with ESMTP id CAE5F8FC1B for ; Sun, 15 Jun 2008 14:10:27 +0000 (UTC) (envelope-from gk@FreeBSD.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.1/8.14.1) with ESMTP id m5FEARui025069 for ; Sun, 15 Jun 2008 14:10:27 GMT (envelope-from gk@FreeBSD.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.1/8.14.1/Submit) id m5FEAR46025067 for perforce@freebsd.org; Sun, 15 Jun 2008 14:10:27 GMT (envelope-from gk@FreeBSD.org) Date: Sun, 15 Jun 2008 14:10:27 GMT Message-Id: <200806151410.m5FEAR46025067@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to gk@FreeBSD.org using -f From: Gleb Kurtsou To: Perforce Change Reviews Cc: Subject: PERFORCE change 143510 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 15 Jun 2008 14:10:28 -0000 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;