View | Details | Raw Unified | Return to bug 217292
Collapse All | Expand All

(-)stable/11/sys/netpfil/ipfw/ip_fw2.c (-64 / +110 lines)
Lines 382-388 iface_match(struct ifnet *ifp, ipfw_insn_if *cmd, Link Here
382
	/* Check by name or by IP address */
382
	/* Check by name or by IP address */
383
	if (cmd->name[0] != '\0') { /* match by name */
383
	if (cmd->name[0] != '\0') { /* match by name */
384
		if (cmd->name[0] == '\1') /* use tablearg to match */
384
		if (cmd->name[0] == '\1') /* use tablearg to match */
385
			return ipfw_lookup_table_extended(chain, cmd->p.kidx, 0,
385
			return ipfw_lookup_table(chain, cmd->p.kidx, 0,
386
				&ifp->if_index, tablearg);
386
				&ifp->if_index, tablearg);
387
		/* Check name */
387
		/* Check name */
388
		if (cmd->p.glob) {
388
		if (cmd->p.glob) {
Lines 1454-1541 do { \ Link Here
1454
				    src_ip.s_addr);
1454
				    src_ip.s_addr);
1455
				break;
1455
				break;
1456
1456
1457
			case O_IP_SRC_LOOKUP:
1458
			case O_IP_DST_LOOKUP:
1457
			case O_IP_DST_LOOKUP:
1459
				if (is_ipv4) {
1458
			{
1460
				    uint32_t key =
1459
				void *pkey;
1461
					(cmd->opcode == O_IP_DST_LOOKUP) ?
1460
				uint32_t vidx, key;
1462
					    dst_ip.s_addr : src_ip.s_addr;
1461
				uint16_t keylen;
1463
				    uint32_t v = 0;
1464
1462
1465
				    if (cmdlen > F_INSN_SIZE(ipfw_insn_u32)) {
1463
				if (cmdlen > F_INSN_SIZE(ipfw_insn_u32)) {
1466
					/* generic lookup. The key must be
1464
					/* Determine lookup key type */
1467
					 * in 32bit big-endian format.
1465
					vidx = ((ipfw_insn_u32 *)cmd)->d[1];
1468
					 */
1466
					if (vidx != 4 /* uid */ &&
1469
					v = ((ipfw_insn_u32 *)cmd)->d[1];
1467
					    vidx != 5 /* jail */ &&
1470
					if (v == 0)
1468
					    is_ipv6 == 0 && is_ipv4 == 0)
1471
					    key = dst_ip.s_addr;
1469
						break;
1472
					else if (v == 1)
1470
					/* Determine key length */
1473
					    key = src_ip.s_addr;
1471
					if (vidx == 0 /* dst-ip */ ||
1474
					else if (v == 6) /* dscp */
1472
					    vidx == 1 /* src-ip */)
1475
					    key = (ip->ip_tos >> 2) & 0x3f;
1473
						keylen = is_ipv6 ?
1476
					else if (offset != 0)
1474
						    sizeof(struct in6_addr):
1477
					    break;
1475
						    sizeof(in_addr_t);
1478
					else if (proto != IPPROTO_TCP &&
1476
					else {
1479
						proto != IPPROTO_UDP)
1477
						keylen = sizeof(key);
1480
					    break;
1478
						pkey = &key;
1481
					else if (v == 2)
1479
					}
1482
					    key = dst_port;
1480
					if (vidx == 0 /* dst-ip */)
1483
					else if (v == 3)
1481
						pkey = is_ipv4 ? (void *)&dst_ip:
1484
					    key = src_port;
1482
						    (void *)&args->f_id.dst_ip6;
1483
					else if (vidx == 1 /* src-ip */)
1484
						pkey = is_ipv4 ? (void *)&src_ip:
1485
						    (void *)&args->f_id.src_ip6;
1486
					else if (vidx == 6 /* dscp */) {
1487
						if (is_ipv4)
1488
							key = ip->ip_tos >> 2;
1489
						else {
1490
							key = args->f_id.flow_id6;
1491
							key = (key & 0x0f) << 2 |
1492
							    (key & 0xf000) >> 14;
1493
						}
1494
						key &= 0x3f;
1495
					} else if (vidx == 2 /* dst-port */ ||
1496
					    vidx == 3 /* src-port */) {
1497
						/* Skip fragments */
1498
						if (offset != 0)
1499
							break;
1500
						/* Skip proto without ports */
1501
						if (proto != IPPROTO_TCP &&
1502
						    proto != IPPROTO_UDP &&
1503
						    proto != IPPROTO_SCTP)
1504
							break;
1505
						if (vidx == 2 /* dst-port */)
1506
							key = dst_port;
1507
						else
1508
							key = src_port;
1509
					}
1485
#ifndef USERSPACE
1510
#ifndef USERSPACE
1486
					else if (v == 4 || v == 5) {
1511
					else if (vidx == 4 /* uid */ ||
1487
					    check_uidgid(
1512
					    vidx == 5 /* jail */) {
1488
						(ipfw_insn_u32 *)cmd,
1513
						check_uidgid(
1489
						args, &ucred_lookup,
1514
						    (ipfw_insn_u32 *)cmd,
1515
						    args, &ucred_lookup,
1490
#ifdef __FreeBSD__
1516
#ifdef __FreeBSD__
1491
						&ucred_cache);
1517
						    &ucred_cache);
1492
					    if (v == 4 /* O_UID */)
1518
						if (vidx == 4 /* uid */)
1493
						key = ucred_cache->cr_uid;
1519
							key = ucred_cache->cr_uid;
1494
					    else if (v == 5 /* O_JAIL */)
1520
						else if (vidx == 5 /* jail */)
1495
						key = ucred_cache->cr_prison->pr_id;
1521
							key = ucred_cache->cr_prison->pr_id;
1496
#else /* !__FreeBSD__ */
1522
#else /* !__FreeBSD__ */
1497
						(void *)&ucred_cache);
1523
						    (void *)&ucred_cache);
1498
					    if (v ==4 /* O_UID */)
1524
						if (vidx == 4 /* uid */)
1499
						key = ucred_cache.uid;
1525
							key = ucred_cache.uid;
1500
					    else if (v == 5 /* O_JAIL */)
1526
						else if (vidx == 5 /* jail */)
1501
						key = ucred_cache.xid;
1527
							key = ucred_cache.xid;
1502
#endif /* !__FreeBSD__ */
1528
#endif /* !__FreeBSD__ */
1503
					}
1529
					}
1504
#endif /* !USERSPACE */
1530
#endif /* !USERSPACE */
1505
					else
1531
					else
1506
					    break;
1532
						break;
1507
				    }
1533
					match = ipfw_lookup_table(chain,
1508
				    match = ipfw_lookup_table(chain,
1534
					    cmd->arg1, keylen, pkey, &vidx);
1509
					cmd->arg1, key, &v);
1535
					if (!match)
1510
				    if (!match)
1536
						break;
1537
					tablearg = vidx;
1511
					break;
1538
					break;
1512
				    if (cmdlen == F_INSN_SIZE(ipfw_insn_u32))
1539
				}
1513
					match =
1540
				/* cmdlen =< F_INSN_SIZE(ipfw_insn_u32) */
1514
					    ((ipfw_insn_u32 *)cmd)->d[0] == v;
1541
				/* FALLTHROUGH */
1515
				    else
1542
			}
1516
					tablearg = v;
1543
			case O_IP_SRC_LOOKUP:
1544
			{
1545
				void *pkey;
1546
				uint32_t vidx;
1547
				uint16_t keylen;
1548
1549
				if (is_ipv4) {
1550
					keylen = sizeof(in_addr_t);
1551
					if (cmd->opcode == O_IP_DST_LOOKUP)
1552
						pkey = &dst_ip;
1553
					else
1554
						pkey = &src_ip;
1517
				} else if (is_ipv6) {
1555
				} else if (is_ipv6) {
1518
					uint32_t v = 0;
1556
					keylen = sizeof(struct in6_addr);
1519
					void *pkey = (cmd->opcode == O_IP_DST_LOOKUP) ?
1557
					if (cmd->opcode == O_IP_DST_LOOKUP)
1520
						&args->f_id.dst_ip6: &args->f_id.src_ip6;
1558
						pkey = &args->f_id.dst_ip6;
1521
					match = ipfw_lookup_table_extended(chain,
1559
					else
1522
							cmd->arg1,
1560
						pkey = &args->f_id.src_ip6;
1523
							sizeof(struct in6_addr),
1561
				} else
1524
							pkey, &v);
1562
					break;
1525
					if (cmdlen == F_INSN_SIZE(ipfw_insn_u32))
1563
				match = ipfw_lookup_table(chain, cmd->arg1,
1526
						match = ((ipfw_insn_u32 *)cmd)->d[0] == v;
1564
				    keylen, pkey, &vidx);
1527
					if (match)
1565
				if (!match)
1528
						tablearg = v;
1566
					break;
1567
				if (cmdlen == F_INSN_SIZE(ipfw_insn_u32)) {
1568
					match = ((ipfw_insn_u32 *)cmd)->d[0] ==
1569
					    TARG_VAL(chain, vidx, tag);
1570
					if (!match)
1571
						break;
1529
				}
1572
				}
1573
				tablearg = vidx;
1530
				break;
1574
				break;
1575
			}
1531
1576
1532
			case O_IP_FLOW_LOOKUP:
1577
			case O_IP_FLOW_LOOKUP:
1533
				{
1578
				{
1534
					uint32_t v = 0;
1579
					uint32_t v = 0;
1535
					match = ipfw_lookup_table_extended(chain,
1580
					match = ipfw_lookup_table(chain,
1536
					    cmd->arg1, 0, &args->f_id, &v);
1581
					    cmd->arg1, 0, &args->f_id, &v);
1537
					if (cmdlen == F_INSN_SIZE(ipfw_insn_u32))
1582
					if (cmdlen == F_INSN_SIZE(ipfw_insn_u32))
1538
						match = ((ipfw_insn_u32 *)cmd)->d[0] == v;
1583
						match = ((ipfw_insn_u32 *)cmd)->d[0] ==
1584
						    TARG_VAL(chain, v, tag);
1539
					if (match)
1585
					if (match)
1540
						tablearg = v;
1586
						tablearg = v;
1541
				}
1587
				}
(-)stable/11/sys/netpfil/ipfw/ip_fw_private.h (-3 / +1 lines)
Lines 739-747 struct table_info; Link Here
739
typedef int (table_lookup_t)(struct table_info *ti, void *key, uint32_t keylen,
739
typedef int (table_lookup_t)(struct table_info *ti, void *key, uint32_t keylen,
740
    uint32_t *val);
740
    uint32_t *val);
741
741
742
int ipfw_lookup_table(struct ip_fw_chain *ch, uint16_t tbl, in_addr_t addr,
742
int ipfw_lookup_table(struct ip_fw_chain *ch, uint16_t tbl, uint16_t plen,
743
    uint32_t *val);
744
int ipfw_lookup_table_extended(struct ip_fw_chain *ch, uint16_t tbl, uint16_t plen,
745
    void *paddr, uint32_t *val);
743
    void *paddr, uint32_t *val);
746
int ipfw_init_tables(struct ip_fw_chain *ch, int first);
744
int ipfw_init_tables(struct ip_fw_chain *ch, int first);
747
int ipfw_resize_tables(struct ip_fw_chain *ch, unsigned int ntables);
745
int ipfw_resize_tables(struct ip_fw_chain *ch, unsigned int ntables);
(-)stable/11/sys/netpfil/ipfw/ip_fw_sockopt.c (+2 lines)
Lines 1821-1826 check_ipfw_rule_body(ipfw_insn *cmd, int cmd_len, Link Here
1821
			break;
1821
			break;
1822
1822
1823
		case O_IP_SRC_LOOKUP:
1823
		case O_IP_SRC_LOOKUP:
1824
			if (cmdlen > F_INSN_SIZE(ipfw_insn_u32))
1825
				goto bad_size;
1824
		case O_IP_DST_LOOKUP:
1826
		case O_IP_DST_LOOKUP:
1825
			if (cmd->arg1 >= V_fw_tables_max) {
1827
			if (cmd->arg1 >= V_fw_tables_max) {
1826
				printf("ipfw: invalid table number %d\n",
1828
				printf("ipfw: invalid table number %d\n",
(-)stable/11/sys/netpfil/ipfw/ip_fw_table.c (-18 / +1 lines)
Lines 1606-1628 ipfw_resize_tables(struct ip_fw_chain *ch, unsigne Link Here
1606
}
1606
}
1607
1607
1608
/*
1608
/*
1609
 * Lookup an IP @addr in table @tbl.
1610
 * Stores found value in @val.
1611
 *
1612
 * Returns 1 if @addr was found.
1613
 */
1614
int
1615
ipfw_lookup_table(struct ip_fw_chain *ch, uint16_t tbl, in_addr_t addr,
1616
    uint32_t *val)
1617
{
1618
	struct table_info *ti;
1619
1620
	ti = KIDX_TO_TI(ch, tbl);
1621
1622
	return (ti->lookup(ti, &addr, sizeof(in_addr_t), val));
1623
}
1624
1625
/*
1626
 * Lookup an arbtrary key @paddr of legth @plen in table @tbl.
1609
 * Lookup an arbtrary key @paddr of legth @plen in table @tbl.
1627
 * Stores found value in @val.
1610
 * Stores found value in @val.
1628
 *
1611
 *
Lines 1629-1635 ipfw_resize_tables(struct ip_fw_chain *ch, unsigne Link Here
1629
 * Returns 1 if key was found.
1612
 * Returns 1 if key was found.
1630
 */
1613
 */
1631
int
1614
int
1632
ipfw_lookup_table_extended(struct ip_fw_chain *ch, uint16_t tbl, uint16_t plen,
1615
ipfw_lookup_table(struct ip_fw_chain *ch, uint16_t tbl, uint16_t plen,
1633
    void *paddr, uint32_t *val)
1616
    void *paddr, uint32_t *val)
1634
{
1617
{
1635
	struct table_info *ti;
1618
	struct table_info *ti;

Return to bug 217292