From owner-p4-projects@FreeBSD.ORG Tue Jun 10 18:03:32 2008 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 051361065672; Tue, 10 Jun 2008 18:03:32 +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 A1641106566B for ; Tue, 10 Jun 2008 18:03:31 +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 931648FC0A for ; Tue, 10 Jun 2008 18:03:31 +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 m5AI3VAj018532 for ; Tue, 10 Jun 2008 18:03:31 GMT (envelope-from gk@FreeBSD.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.1/8.14.1/Submit) id m5AI3VMw018530 for perforce@freebsd.org; Tue, 10 Jun 2008 18:03:31 GMT (envelope-from gk@FreeBSD.org) Date: Tue, 10 Jun 2008 18:03:31 GMT Message-Id: <200806101803.m5AI3VMw018530@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 143248 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: Tue, 10 Jun 2008 18:03:32 -0000 http://perforce.freebsd.org/chv.cgi?CH=143248 Change 143248 by gk@gk_h1 on 2008/06/10 18:03:17 support filtering by mac in ipfw lookup tables example: ~ # ipfw add allow ip from 'table(1)' to any in recv if_home ~ # ipfw table 1 add 192.168.1.1 ether 00:a0:c9:dd:23:47 Affected files ... .. //depot/projects/soc2008/gk_l2filter/sbin-ipfw/ipfw2.c#3 edit .. //depot/projects/soc2008/gk_l2filter/sys-netinet/ip_fw.h#4 edit .. //depot/projects/soc2008/gk_l2filter/sys-netinet/ip_fw2.c#5 edit Differences ... ==== //depot/projects/soc2008/gk_l2filter/sbin-ipfw/ipfw2.c#3 (text+ko) ==== @@ -5966,6 +5966,12 @@ if (lookup_host(*av, (struct in_addr *)&ent.addr) != 0) errx(EX_NOHOST, "hostname ``%s'' unknown", *av); ac--; av++; + ent.mac_addr = 0; + if (do_add && ac >= 2 && strcmp(*av, "mac") == 0) { + uint8_t mask[8]; + get_mac_addr_mask(av[1], (uint8_t*)&ent.mac_addr, mask); + ac-=2; av+=2; + } if (do_add && ac) { unsigned int tval; /* isdigit is a bit of a hack here.. */ @@ -6014,20 +6020,28 @@ err(EX_OSERR, "getsockopt(IP_FW_TABLE_LIST)"); for (a = 0; a < tbl->cnt; a++) { unsigned int tval; + char tval_buf[128]; + char tmac_buf[128]; tval = tbl->ent[a].value; if (do_value_as_ip) { - char tbuf[128]; - strncpy(tbuf, inet_ntoa(*(struct in_addr *) - &tbl->ent[a].addr), 127); /* inet_ntoa expects network order */ tval = htonl(tval); - printf("%s/%u %s\n", tbuf, tbl->ent[a].masklen, - inet_ntoa(*(struct in_addr *)&tval)); + strlcpy(tval_buf, inet_ntoa(*(struct in_addr *) + &tval), sizeof(tval_buf)); + } else { + snprintf(tval_buf, sizeof(tval_buf), "%u", tval); + } + if (tbl->ent[a].mac_addr) { + uint8_t *x = (uint8_t *)&tbl->ent[a].mac_addr; + snprintf(tmac_buf, sizeof(tmac_buf), "mac %02x:%02x:%02x:%02x:%02x:%02x ", + x[0], x[1], x[2], x[3], x[4], x[5]); } else { - printf("%s/%u %u\n", - inet_ntoa(*(struct in_addr *)&tbl->ent[a].addr), - tbl->ent[a].masklen, tval); + tmac_buf[0] = 0; } + + printf("%s/%u %s%s\n", + inet_ntoa(*(struct in_addr *)&tbl->ent[a].addr), + tbl->ent[a].masklen, tmac_buf, tval_buf); } } else errx(EX_USAGE, "invalid table command %s", *av); ==== //depot/projects/soc2008/gk_l2filter/sys-netinet/ip_fw.h#4 (text+ko) ==== @@ -533,6 +533,7 @@ */ typedef struct _ipfw_table_entry { in_addr_t addr; /* network address */ + u_int64_t mac_addr; /* mac address */ u_int32_t value; /* value */ u_int16_t tbl; /* table number */ u_int8_t masklen; /* mask length */ ==== //depot/projects/soc2008/gk_l2filter/sys-netinet/ip_fw2.c#5 (text+ko) ==== @@ -153,6 +153,7 @@ struct table_entry { struct radix_node rn[2]; struct sockaddr_in addr, mask; + u_int64_t mac_addr; u_int32_t value; }; @@ -1752,7 +1753,7 @@ static int add_table_entry(struct ip_fw_chain *ch, uint16_t tbl, in_addr_t addr, - uint8_t mlen, uint32_t value) + uint8_t mlen, u_int64_t mac_addr, uint32_t value) { struct radix_node_head *rnh; struct table_entry *ent; @@ -1767,6 +1768,7 @@ ent->addr.sin_len = ent->mask.sin_len = 8; ent->mask.sin_addr.s_addr = htonl(mlen ? ~((1 << (32 - mlen)) - 1) : 0); ent->addr.sin_addr.s_addr = addr & ent->mask.sin_addr.s_addr; + ent->mac_addr = mac_addr; IPFW_WLOCK(&layer3_chain); if (rnh->rnh_addaddr(&ent->addr, &ent->mask, rnh, (void *)ent) == NULL) { @@ -1861,7 +1863,7 @@ static int lookup_table(struct ip_fw_chain *ch, uint16_t tbl, in_addr_t addr, - uint32_t *val) + struct ether_addr *ea, uint32_t *val) { struct radix_node_head *rnh; struct table_entry *ent; @@ -1874,6 +1876,10 @@ sa.sin_addr.s_addr = addr; ent = (struct table_entry *)(rnh->rnh_lookup(&sa, NULL, rnh)); if (ent != NULL) { + if (ea && ent->mac_addr) { + if (ent->mac_addr != ((*(u_int64_t*)ea))) + return (0); + } *val = ent->value; return (1); } @@ -1918,6 +1924,7 @@ else ent->masklen = 33 - ffs(ntohl(n->mask.sin_addr.s_addr)); ent->addr = n->addr.sin_addr.s_addr; + ent->mac_addr = n->mac_addr; ent->value = n->value; tbl->cnt++; return (0); @@ -2649,13 +2656,19 @@ case O_IP_SRC_LOOKUP: case O_IP_DST_LOOKUP: if (is_ipv4) { + struct ether_addr *ea = NULL; uint32_t a = (cmd->opcode == O_IP_DST_LOOKUP) ? dst_ip.s_addr : src_ip.s_addr; uint32_t v; + if (args->eh) { + ea = (struct ether_addr*)((cmd->opcode == O_IP_DST_LOOKUP) ? + args->eh->ether_dhost : + args->eh->ether_shost); + } match = lookup_table(chain, cmd->arg1, a, - &v); + ea, &v); if (!match) break; if (cmdlen == F_INSN_SIZE(ipfw_insn_u32)) @@ -4267,7 +4280,7 @@ if (error) break; error = add_table_entry(&layer3_chain, ent.tbl, - ent.addr, ent.masklen, ent.value); + ent.addr, ent.masklen, ent.mac_addr, ent.value); } break;