aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv4')
-rw-r--r--net/ipv4/netfilter/ip_tables.c78
1 files changed, 61 insertions, 17 deletions
diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c
index 9c8aa394c51..3a7fc732b91 100644
--- a/net/ipv4/netfilter/ip_tables.c
+++ b/net/ipv4/netfilter/ip_tables.c
@@ -366,16 +366,21 @@ ipt_do_table(struct sk_buff *skb,
366 366
367 do { 367 do {
368 const struct ipt_entry_target *t; 368 const struct ipt_entry_target *t;
369 const struct xt_entry_match *ematch;
369 370
370 IP_NF_ASSERT(e); 371 IP_NF_ASSERT(e);
371 IP_NF_ASSERT(back); 372 IP_NF_ASSERT(back);
372 if (!ip_packet_match(ip, indev, outdev, 373 if (!ip_packet_match(ip, indev, outdev,
373 &e->ip, mtpar.fragoff) || 374 &e->ip, mtpar.fragoff)) {
374 IPT_MATCH_ITERATE(e, do_match, skb, &mtpar) != 0) { 375 no_match:
375 e = ipt_next_entry(e); 376 e = ipt_next_entry(e);
376 continue; 377 continue;
377 } 378 }
378 379
380 xt_ematch_foreach(ematch, e)
381 if (do_match(ematch, skb, &mtpar) != 0)
382 goto no_match;
383
379 ADD_COUNTER(e->counters, ntohs(ip->tot_len), 1); 384 ADD_COUNTER(e->counters, ntohs(ip->tot_len), 1);
380 385
381 t = ipt_get_target(e); 386 t = ipt_get_target(e);
@@ -686,6 +691,7 @@ find_check_entry(struct ipt_entry *e, struct net *net, const char *name,
686 int ret; 691 int ret;
687 unsigned int j; 692 unsigned int j;
688 struct xt_mtchk_param mtpar; 693 struct xt_mtchk_param mtpar;
694 struct xt_entry_match *ematch;
689 695
690 ret = check_entry(e, name); 696 ret = check_entry(e, name);
691 if (ret) 697 if (ret)
@@ -697,7 +703,11 @@ find_check_entry(struct ipt_entry *e, struct net *net, const char *name,
697 mtpar.entryinfo = &e->ip; 703 mtpar.entryinfo = &e->ip;
698 mtpar.hook_mask = e->comefrom; 704 mtpar.hook_mask = e->comefrom;
699 mtpar.family = NFPROTO_IPV4; 705 mtpar.family = NFPROTO_IPV4;
700 ret = IPT_MATCH_ITERATE(e, find_check_match, &mtpar, &j); 706 xt_ematch_foreach(ematch, e) {
707 ret = find_check_match(ematch, &mtpar, &j);
708 if (ret != 0)
709 break;
710 }
701 if (ret != 0) 711 if (ret != 0)
702 goto cleanup_matches; 712 goto cleanup_matches;
703 713
@@ -720,7 +730,9 @@ find_check_entry(struct ipt_entry *e, struct net *net, const char *name,
720 err: 730 err:
721 module_put(t->u.kernel.target->me); 731 module_put(t->u.kernel.target->me);
722 cleanup_matches: 732 cleanup_matches:
723 IPT_MATCH_ITERATE(e, cleanup_match, net, &j); 733 xt_ematch_foreach(ematch, e)
734 if (cleanup_match(ematch, net, &j) != 0)
735 break;
724 return ret; 736 return ret;
725} 737}
726 738
@@ -791,9 +803,12 @@ cleanup_entry(struct ipt_entry *e, struct net *net)
791{ 803{
792 struct xt_tgdtor_param par; 804 struct xt_tgdtor_param par;
793 struct ipt_entry_target *t; 805 struct ipt_entry_target *t;
806 struct xt_entry_match *ematch;
794 807
795 /* Cleanup all matches */ 808 /* Cleanup all matches */
796 IPT_MATCH_ITERATE(e, cleanup_match, net, NULL); 809 xt_ematch_foreach(ematch, e)
810 if (cleanup_match(ematch, net, NULL) != 0)
811 break;
797 t = ipt_get_target(e); 812 t = ipt_get_target(e);
798 813
799 par.net = net; 814 par.net = net;
@@ -1060,13 +1075,16 @@ static int compat_calc_entry(const struct ipt_entry *e,
1060 const struct xt_table_info *info, 1075 const struct xt_table_info *info,
1061 const void *base, struct xt_table_info *newinfo) 1076 const void *base, struct xt_table_info *newinfo)
1062{ 1077{
1078 const struct xt_entry_match *ematch;
1063 const struct ipt_entry_target *t; 1079 const struct ipt_entry_target *t;
1064 unsigned int entry_offset; 1080 unsigned int entry_offset;
1065 int off, i, ret; 1081 int off, i, ret;
1066 1082
1067 off = sizeof(struct ipt_entry) - sizeof(struct compat_ipt_entry); 1083 off = sizeof(struct ipt_entry) - sizeof(struct compat_ipt_entry);
1068 entry_offset = (void *)e - base; 1084 entry_offset = (void *)e - base;
1069 IPT_MATCH_ITERATE(e, compat_calc_match, &off); 1085 xt_ematch_foreach(ematch, e)
1086 if (compat_calc_match(ematch, &off) != 0)
1087 break;
1070 t = ipt_get_target_c(e); 1088 t = ipt_get_target_c(e);
1071 off += xt_compat_target_offset(t->u.kernel.target); 1089 off += xt_compat_target_offset(t->u.kernel.target);
1072 newinfo->size -= off; 1090 newinfo->size -= off;
@@ -1441,7 +1459,8 @@ compat_copy_entry_to_user(struct ipt_entry *e, void __user **dstptr,
1441 struct compat_ipt_entry __user *ce; 1459 struct compat_ipt_entry __user *ce;
1442 u_int16_t target_offset, next_offset; 1460 u_int16_t target_offset, next_offset;
1443 compat_uint_t origsize; 1461 compat_uint_t origsize;
1444 int ret; 1462 const struct xt_entry_match *ematch;
1463 int ret = 0;
1445 1464
1446 origsize = *size; 1465 origsize = *size;
1447 ce = (struct compat_ipt_entry __user *)*dstptr; 1466 ce = (struct compat_ipt_entry __user *)*dstptr;
@@ -1453,7 +1472,11 @@ compat_copy_entry_to_user(struct ipt_entry *e, void __user **dstptr,
1453 *dstptr += sizeof(struct compat_ipt_entry); 1472 *dstptr += sizeof(struct compat_ipt_entry);
1454 *size -= sizeof(struct ipt_entry) - sizeof(struct compat_ipt_entry); 1473 *size -= sizeof(struct ipt_entry) - sizeof(struct compat_ipt_entry);
1455 1474
1456 ret = IPT_MATCH_ITERATE(e, xt_compat_match_to_user, dstptr, size); 1475 xt_ematch_foreach(ematch, e) {
1476 ret = xt_compat_match_to_user(ematch, dstptr, size);
1477 if (ret != 0)
1478 break;
1479 }
1457 target_offset = e->target_offset - (origsize - *size); 1480 target_offset = e->target_offset - (origsize - *size);
1458 if (ret) 1481 if (ret)
1459 return ret; 1482 return ret;
@@ -1505,9 +1528,12 @@ compat_release_match(struct ipt_entry_match *m, unsigned int *i)
1505static void compat_release_entry(struct compat_ipt_entry *e) 1528static void compat_release_entry(struct compat_ipt_entry *e)
1506{ 1529{
1507 struct ipt_entry_target *t; 1530 struct ipt_entry_target *t;
1531 struct xt_entry_match *ematch;
1508 1532
1509 /* Cleanup all matches */ 1533 /* Cleanup all matches */
1510 COMPAT_IPT_MATCH_ITERATE(e, compat_release_match, NULL); 1534 xt_ematch_foreach(ematch, e)
1535 if (compat_release_match(ematch, NULL) != 0)
1536 break;
1511 t = compat_ipt_get_target(e); 1537 t = compat_ipt_get_target(e);
1512 module_put(t->u.kernel.target->me); 1538 module_put(t->u.kernel.target->me);
1513} 1539}
@@ -1522,6 +1548,7 @@ check_compat_entry_size_and_hooks(struct compat_ipt_entry *e,
1522 const unsigned int *underflows, 1548 const unsigned int *underflows,
1523 const char *name) 1549 const char *name)
1524{ 1550{
1551 struct xt_entry_match *ematch;
1525 struct ipt_entry_target *t; 1552 struct ipt_entry_target *t;
1526 struct xt_target *target; 1553 struct xt_target *target;
1527 unsigned int entry_offset; 1554 unsigned int entry_offset;
@@ -1550,8 +1577,12 @@ check_compat_entry_size_and_hooks(struct compat_ipt_entry *e,
1550 off = sizeof(struct ipt_entry) - sizeof(struct compat_ipt_entry); 1577 off = sizeof(struct ipt_entry) - sizeof(struct compat_ipt_entry);
1551 entry_offset = (void *)e - (void *)base; 1578 entry_offset = (void *)e - (void *)base;
1552 j = 0; 1579 j = 0;
1553 ret = COMPAT_IPT_MATCH_ITERATE(e, compat_find_calc_match, name, 1580 xt_ematch_foreach(ematch, e) {
1554 &e->ip, e->comefrom, &off, &j); 1581 ret = compat_find_calc_match(ematch, name,
1582 &e->ip, e->comefrom, &off, &j);
1583 if (ret != 0)
1584 break;
1585 }
1555 if (ret != 0) 1586 if (ret != 0)
1556 goto release_matches; 1587 goto release_matches;
1557 1588
@@ -1590,7 +1621,9 @@ check_compat_entry_size_and_hooks(struct compat_ipt_entry *e,
1590out: 1621out:
1591 module_put(t->u.kernel.target->me); 1622 module_put(t->u.kernel.target->me);
1592release_matches: 1623release_matches:
1593 IPT_MATCH_ITERATE(e, compat_release_match, &j); 1624 xt_ematch_foreach(ematch, e)
1625 if (compat_release_match(ematch, &j) != 0)
1626 break;
1594 return ret; 1627 return ret;
1595} 1628}
1596 1629
@@ -1604,6 +1637,7 @@ compat_copy_entry_from_user(struct compat_ipt_entry *e, void **dstptr,
1604 struct ipt_entry *de; 1637 struct ipt_entry *de;
1605 unsigned int origsize; 1638 unsigned int origsize;
1606 int ret, h; 1639 int ret, h;
1640 struct xt_entry_match *ematch;
1607 1641
1608 ret = 0; 1642 ret = 0;
1609 origsize = *size; 1643 origsize = *size;
@@ -1614,8 +1648,11 @@ compat_copy_entry_from_user(struct compat_ipt_entry *e, void **dstptr,
1614 *dstptr += sizeof(struct ipt_entry); 1648 *dstptr += sizeof(struct ipt_entry);
1615 *size += sizeof(struct ipt_entry) - sizeof(struct compat_ipt_entry); 1649 *size += sizeof(struct ipt_entry) - sizeof(struct compat_ipt_entry);
1616 1650
1617 ret = COMPAT_IPT_MATCH_ITERATE(e, xt_compat_match_from_user, 1651 xt_ematch_foreach(ematch, e) {
1618 dstptr, size); 1652 ret = xt_compat_match_from_user(ematch, dstptr, size);
1653 if (ret != 0)
1654 break;
1655 }
1619 if (ret) 1656 if (ret)
1620 return ret; 1657 return ret;
1621 de->target_offset = e->target_offset - (origsize - *size); 1658 de->target_offset = e->target_offset - (origsize - *size);
@@ -1636,9 +1673,10 @@ compat_copy_entry_from_user(struct compat_ipt_entry *e, void **dstptr,
1636static int 1673static int
1637compat_check_entry(struct ipt_entry *e, struct net *net, const char *name) 1674compat_check_entry(struct ipt_entry *e, struct net *net, const char *name)
1638{ 1675{
1676 struct xt_entry_match *ematch;
1639 struct xt_mtchk_param mtpar; 1677 struct xt_mtchk_param mtpar;
1640 unsigned int j; 1678 unsigned int j;
1641 int ret; 1679 int ret = 0;
1642 1680
1643 j = 0; 1681 j = 0;
1644 mtpar.net = net; 1682 mtpar.net = net;
@@ -1646,7 +1684,11 @@ compat_check_entry(struct ipt_entry *e, struct net *net, const char *name)
1646 mtpar.entryinfo = &e->ip; 1684 mtpar.entryinfo = &e->ip;
1647 mtpar.hook_mask = e->comefrom; 1685 mtpar.hook_mask = e->comefrom;
1648 mtpar.family = NFPROTO_IPV4; 1686 mtpar.family = NFPROTO_IPV4;
1649 ret = IPT_MATCH_ITERATE(e, check_match, &mtpar, &j); 1687 xt_ematch_foreach(ematch, e) {
1688 ret = check_match(ematch, &mtpar, &j);
1689 if (ret != 0)
1690 break;
1691 }
1650 if (ret) 1692 if (ret)
1651 goto cleanup_matches; 1693 goto cleanup_matches;
1652 1694
@@ -1656,7 +1698,9 @@ compat_check_entry(struct ipt_entry *e, struct net *net, const char *name)
1656 return 0; 1698 return 0;
1657 1699
1658 cleanup_matches: 1700 cleanup_matches:
1659 IPT_MATCH_ITERATE(e, cleanup_match, net, &j); 1701 xt_ematch_foreach(ematch, e)
1702 if (cleanup_match(ematch, net, &j) != 0)
1703 break;
1660 return ret; 1704 return ret;
1661} 1705}
1662 1706