diff options
author | Patrick McHardy <kaber@trash.net> | 2010-02-15 12:14:57 -0500 |
---|---|---|
committer | Patrick McHardy <kaber@trash.net> | 2010-02-15 12:14:57 -0500 |
commit | ef00f89f1eb7e056aab9dfe068521e6f2320c94a (patch) | |
tree | 9e62ade3fe99addbd8704e8798d8d310b810d7e4 /net | |
parent | 5d0aa2ccd4699a01cfdf14886191c249d7b45a01 (diff) |
netfilter: ctnetlink: add zone support
Parse and dump the conntrack zone in ctnetlink.
Signed-off-by: Patrick McHardy <kaber@trash.net>
Diffstat (limited to 'net')
-rw-r--r-- | net/netfilter/nf_conntrack_netlink.c | 92 |
1 files changed, 73 insertions, 19 deletions
diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c index 51089cfe1167..8b05f364b2f2 100644 --- a/net/netfilter/nf_conntrack_netlink.c +++ b/net/netfilter/nf_conntrack_netlink.c | |||
@@ -39,6 +39,7 @@ | |||
39 | #include <net/netfilter/nf_conntrack_l4proto.h> | 39 | #include <net/netfilter/nf_conntrack_l4proto.h> |
40 | #include <net/netfilter/nf_conntrack_tuple.h> | 40 | #include <net/netfilter/nf_conntrack_tuple.h> |
41 | #include <net/netfilter/nf_conntrack_acct.h> | 41 | #include <net/netfilter/nf_conntrack_acct.h> |
42 | #include <net/netfilter/nf_conntrack_zones.h> | ||
42 | #ifdef CONFIG_NF_NAT_NEEDED | 43 | #ifdef CONFIG_NF_NAT_NEEDED |
43 | #include <net/netfilter/nf_nat_core.h> | 44 | #include <net/netfilter/nf_nat_core.h> |
44 | #include <net/netfilter/nf_nat_protocol.h> | 45 | #include <net/netfilter/nf_nat_protocol.h> |
@@ -379,6 +380,9 @@ ctnetlink_fill_info(struct sk_buff *skb, u32 pid, u32 seq, | |||
379 | goto nla_put_failure; | 380 | goto nla_put_failure; |
380 | nla_nest_end(skb, nest_parms); | 381 | nla_nest_end(skb, nest_parms); |
381 | 382 | ||
383 | if (nf_ct_zone(ct)) | ||
384 | NLA_PUT_BE16(skb, CTA_ZONE, htons(nf_ct_zone(ct))); | ||
385 | |||
382 | if (ctnetlink_dump_status(skb, ct) < 0 || | 386 | if (ctnetlink_dump_status(skb, ct) < 0 || |
383 | ctnetlink_dump_timeout(skb, ct) < 0 || | 387 | ctnetlink_dump_timeout(skb, ct) < 0 || |
384 | ctnetlink_dump_counters(skb, ct, IP_CT_DIR_ORIGINAL) < 0 || | 388 | ctnetlink_dump_counters(skb, ct, IP_CT_DIR_ORIGINAL) < 0 || |
@@ -517,6 +521,9 @@ ctnetlink_conntrack_event(unsigned int events, struct nf_ct_event *item) | |||
517 | goto nla_put_failure; | 521 | goto nla_put_failure; |
518 | nla_nest_end(skb, nest_parms); | 522 | nla_nest_end(skb, nest_parms); |
519 | 523 | ||
524 | if (nf_ct_zone(ct)) | ||
525 | NLA_PUT_BE16(skb, CTA_ZONE, htons(nf_ct_zone(ct))); | ||
526 | |||
520 | if (ctnetlink_dump_id(skb, ct) < 0) | 527 | if (ctnetlink_dump_id(skb, ct) < 0) |
521 | goto nla_put_failure; | 528 | goto nla_put_failure; |
522 | 529 | ||
@@ -750,6 +757,21 @@ ctnetlink_parse_tuple(const struct nlattr * const cda[], | |||
750 | return 0; | 757 | return 0; |
751 | } | 758 | } |
752 | 759 | ||
760 | static int | ||
761 | ctnetlink_parse_zone(const struct nlattr *attr, u16 *zone) | ||
762 | { | ||
763 | if (attr) | ||
764 | #ifdef CONFIG_NF_CONNTRACK_ZONES | ||
765 | *zone = ntohs(nla_get_be16(attr)); | ||
766 | #else | ||
767 | return -EOPNOTSUPP; | ||
768 | #endif | ||
769 | else | ||
770 | *zone = 0; | ||
771 | |||
772 | return 0; | ||
773 | } | ||
774 | |||
753 | static const struct nla_policy help_nla_policy[CTA_HELP_MAX+1] = { | 775 | static const struct nla_policy help_nla_policy[CTA_HELP_MAX+1] = { |
754 | [CTA_HELP_NAME] = { .type = NLA_NUL_STRING }, | 776 | [CTA_HELP_NAME] = { .type = NLA_NUL_STRING }, |
755 | }; | 777 | }; |
@@ -781,6 +803,7 @@ static const struct nla_policy ct_nla_policy[CTA_MAX+1] = { | |||
781 | [CTA_ID] = { .type = NLA_U32 }, | 803 | [CTA_ID] = { .type = NLA_U32 }, |
782 | [CTA_NAT_DST] = { .type = NLA_NESTED }, | 804 | [CTA_NAT_DST] = { .type = NLA_NESTED }, |
783 | [CTA_TUPLE_MASTER] = { .type = NLA_NESTED }, | 805 | [CTA_TUPLE_MASTER] = { .type = NLA_NESTED }, |
806 | [CTA_ZONE] = { .type = NLA_U16 }, | ||
784 | }; | 807 | }; |
785 | 808 | ||
786 | static int | 809 | static int |
@@ -794,7 +817,12 @@ ctnetlink_del_conntrack(struct sock *ctnl, struct sk_buff *skb, | |||
794 | struct nf_conn *ct; | 817 | struct nf_conn *ct; |
795 | struct nfgenmsg *nfmsg = nlmsg_data(nlh); | 818 | struct nfgenmsg *nfmsg = nlmsg_data(nlh); |
796 | u_int8_t u3 = nfmsg->nfgen_family; | 819 | u_int8_t u3 = nfmsg->nfgen_family; |
797 | int err = 0; | 820 | u16 zone; |
821 | int err; | ||
822 | |||
823 | err = ctnetlink_parse_zone(cda[CTA_ZONE], &zone); | ||
824 | if (err < 0) | ||
825 | return err; | ||
798 | 826 | ||
799 | if (cda[CTA_TUPLE_ORIG]) | 827 | if (cda[CTA_TUPLE_ORIG]) |
800 | err = ctnetlink_parse_tuple(cda, &tuple, CTA_TUPLE_ORIG, u3); | 828 | err = ctnetlink_parse_tuple(cda, &tuple, CTA_TUPLE_ORIG, u3); |
@@ -811,7 +839,7 @@ ctnetlink_del_conntrack(struct sock *ctnl, struct sk_buff *skb, | |||
811 | if (err < 0) | 839 | if (err < 0) |
812 | return err; | 840 | return err; |
813 | 841 | ||
814 | h = nf_conntrack_find_get(net, 0, &tuple); | 842 | h = nf_conntrack_find_get(net, zone, &tuple); |
815 | if (!h) | 843 | if (!h) |
816 | return -ENOENT; | 844 | return -ENOENT; |
817 | 845 | ||
@@ -856,12 +884,17 @@ ctnetlink_get_conntrack(struct sock *ctnl, struct sk_buff *skb, | |||
856 | struct sk_buff *skb2 = NULL; | 884 | struct sk_buff *skb2 = NULL; |
857 | struct nfgenmsg *nfmsg = nlmsg_data(nlh); | 885 | struct nfgenmsg *nfmsg = nlmsg_data(nlh); |
858 | u_int8_t u3 = nfmsg->nfgen_family; | 886 | u_int8_t u3 = nfmsg->nfgen_family; |
859 | int err = 0; | 887 | u16 zone; |
888 | int err; | ||
860 | 889 | ||
861 | if (nlh->nlmsg_flags & NLM_F_DUMP) | 890 | if (nlh->nlmsg_flags & NLM_F_DUMP) |
862 | return netlink_dump_start(ctnl, skb, nlh, ctnetlink_dump_table, | 891 | return netlink_dump_start(ctnl, skb, nlh, ctnetlink_dump_table, |
863 | ctnetlink_done); | 892 | ctnetlink_done); |
864 | 893 | ||
894 | err = ctnetlink_parse_zone(cda[CTA_ZONE], &zone); | ||
895 | if (err < 0) | ||
896 | return err; | ||
897 | |||
865 | if (cda[CTA_TUPLE_ORIG]) | 898 | if (cda[CTA_TUPLE_ORIG]) |
866 | err = ctnetlink_parse_tuple(cda, &tuple, CTA_TUPLE_ORIG, u3); | 899 | err = ctnetlink_parse_tuple(cda, &tuple, CTA_TUPLE_ORIG, u3); |
867 | else if (cda[CTA_TUPLE_REPLY]) | 900 | else if (cda[CTA_TUPLE_REPLY]) |
@@ -872,7 +905,7 @@ ctnetlink_get_conntrack(struct sock *ctnl, struct sk_buff *skb, | |||
872 | if (err < 0) | 905 | if (err < 0) |
873 | return err; | 906 | return err; |
874 | 907 | ||
875 | h = nf_conntrack_find_get(net, 0, &tuple); | 908 | h = nf_conntrack_find_get(net, zone, &tuple); |
876 | if (!h) | 909 | if (!h) |
877 | return -ENOENT; | 910 | return -ENOENT; |
878 | 911 | ||
@@ -1211,7 +1244,7 @@ ctnetlink_change_conntrack(struct nf_conn *ct, | |||
1211 | } | 1244 | } |
1212 | 1245 | ||
1213 | static struct nf_conn * | 1246 | static struct nf_conn * |
1214 | ctnetlink_create_conntrack(struct net *net, | 1247 | ctnetlink_create_conntrack(struct net *net, u16 zone, |
1215 | const struct nlattr * const cda[], | 1248 | const struct nlattr * const cda[], |
1216 | struct nf_conntrack_tuple *otuple, | 1249 | struct nf_conntrack_tuple *otuple, |
1217 | struct nf_conntrack_tuple *rtuple, | 1250 | struct nf_conntrack_tuple *rtuple, |
@@ -1221,7 +1254,7 @@ ctnetlink_create_conntrack(struct net *net, | |||
1221 | int err = -EINVAL; | 1254 | int err = -EINVAL; |
1222 | struct nf_conntrack_helper *helper; | 1255 | struct nf_conntrack_helper *helper; |
1223 | 1256 | ||
1224 | ct = nf_conntrack_alloc(net, 0, otuple, rtuple, GFP_ATOMIC); | 1257 | ct = nf_conntrack_alloc(net, zone, otuple, rtuple, GFP_ATOMIC); |
1225 | if (IS_ERR(ct)) | 1258 | if (IS_ERR(ct)) |
1226 | return ERR_PTR(-ENOMEM); | 1259 | return ERR_PTR(-ENOMEM); |
1227 | 1260 | ||
@@ -1325,7 +1358,7 @@ ctnetlink_create_conntrack(struct net *net, | |||
1325 | if (err < 0) | 1358 | if (err < 0) |
1326 | goto err2; | 1359 | goto err2; |
1327 | 1360 | ||
1328 | master_h = nf_conntrack_find_get(net, 0, &master); | 1361 | master_h = nf_conntrack_find_get(net, zone, &master); |
1329 | if (master_h == NULL) { | 1362 | if (master_h == NULL) { |
1330 | err = -ENOENT; | 1363 | err = -ENOENT; |
1331 | goto err2; | 1364 | goto err2; |
@@ -1358,7 +1391,12 @@ ctnetlink_new_conntrack(struct sock *ctnl, struct sk_buff *skb, | |||
1358 | struct nf_conntrack_tuple_hash *h = NULL; | 1391 | struct nf_conntrack_tuple_hash *h = NULL; |
1359 | struct nfgenmsg *nfmsg = nlmsg_data(nlh); | 1392 | struct nfgenmsg *nfmsg = nlmsg_data(nlh); |
1360 | u_int8_t u3 = nfmsg->nfgen_family; | 1393 | u_int8_t u3 = nfmsg->nfgen_family; |
1361 | int err = 0; | 1394 | u16 zone; |
1395 | int err; | ||
1396 | |||
1397 | err = ctnetlink_parse_zone(cda[CTA_ZONE], &zone); | ||
1398 | if (err < 0) | ||
1399 | return err; | ||
1362 | 1400 | ||
1363 | if (cda[CTA_TUPLE_ORIG]) { | 1401 | if (cda[CTA_TUPLE_ORIG]) { |
1364 | err = ctnetlink_parse_tuple(cda, &otuple, CTA_TUPLE_ORIG, u3); | 1402 | err = ctnetlink_parse_tuple(cda, &otuple, CTA_TUPLE_ORIG, u3); |
@@ -1374,9 +1412,9 @@ ctnetlink_new_conntrack(struct sock *ctnl, struct sk_buff *skb, | |||
1374 | 1412 | ||
1375 | spin_lock_bh(&nf_conntrack_lock); | 1413 | spin_lock_bh(&nf_conntrack_lock); |
1376 | if (cda[CTA_TUPLE_ORIG]) | 1414 | if (cda[CTA_TUPLE_ORIG]) |
1377 | h = __nf_conntrack_find(net, 0, &otuple); | 1415 | h = __nf_conntrack_find(net, zone, &otuple); |
1378 | else if (cda[CTA_TUPLE_REPLY]) | 1416 | else if (cda[CTA_TUPLE_REPLY]) |
1379 | h = __nf_conntrack_find(net, 0, &rtuple); | 1417 | h = __nf_conntrack_find(net, zone, &rtuple); |
1380 | 1418 | ||
1381 | if (h == NULL) { | 1419 | if (h == NULL) { |
1382 | err = -ENOENT; | 1420 | err = -ENOENT; |
@@ -1384,7 +1422,7 @@ ctnetlink_new_conntrack(struct sock *ctnl, struct sk_buff *skb, | |||
1384 | struct nf_conn *ct; | 1422 | struct nf_conn *ct; |
1385 | enum ip_conntrack_events events; | 1423 | enum ip_conntrack_events events; |
1386 | 1424 | ||
1387 | ct = ctnetlink_create_conntrack(net, cda, &otuple, | 1425 | ct = ctnetlink_create_conntrack(net, zone, cda, &otuple, |
1388 | &rtuple, u3); | 1426 | &rtuple, u3); |
1389 | if (IS_ERR(ct)) { | 1427 | if (IS_ERR(ct)) { |
1390 | err = PTR_ERR(ct); | 1428 | err = PTR_ERR(ct); |
@@ -1698,7 +1736,8 @@ ctnetlink_get_expect(struct sock *ctnl, struct sk_buff *skb, | |||
1698 | struct sk_buff *skb2; | 1736 | struct sk_buff *skb2; |
1699 | struct nfgenmsg *nfmsg = nlmsg_data(nlh); | 1737 | struct nfgenmsg *nfmsg = nlmsg_data(nlh); |
1700 | u_int8_t u3 = nfmsg->nfgen_family; | 1738 | u_int8_t u3 = nfmsg->nfgen_family; |
1701 | int err = 0; | 1739 | u16 zone; |
1740 | int err; | ||
1702 | 1741 | ||
1703 | if (nlh->nlmsg_flags & NLM_F_DUMP) { | 1742 | if (nlh->nlmsg_flags & NLM_F_DUMP) { |
1704 | return netlink_dump_start(ctnl, skb, nlh, | 1743 | return netlink_dump_start(ctnl, skb, nlh, |
@@ -1706,6 +1745,10 @@ ctnetlink_get_expect(struct sock *ctnl, struct sk_buff *skb, | |||
1706 | ctnetlink_exp_done); | 1745 | ctnetlink_exp_done); |
1707 | } | 1746 | } |
1708 | 1747 | ||
1748 | err = ctnetlink_parse_zone(cda[CTA_EXPECT_ZONE], &zone); | ||
1749 | if (err < 0) | ||
1750 | return err; | ||
1751 | |||
1709 | if (cda[CTA_EXPECT_MASTER]) | 1752 | if (cda[CTA_EXPECT_MASTER]) |
1710 | err = ctnetlink_parse_tuple(cda, &tuple, CTA_EXPECT_MASTER, u3); | 1753 | err = ctnetlink_parse_tuple(cda, &tuple, CTA_EXPECT_MASTER, u3); |
1711 | else | 1754 | else |
@@ -1714,7 +1757,7 @@ ctnetlink_get_expect(struct sock *ctnl, struct sk_buff *skb, | |||
1714 | if (err < 0) | 1757 | if (err < 0) |
1715 | return err; | 1758 | return err; |
1716 | 1759 | ||
1717 | exp = nf_ct_expect_find_get(net, 0, &tuple); | 1760 | exp = nf_ct_expect_find_get(net, zone, &tuple); |
1718 | if (!exp) | 1761 | if (!exp) |
1719 | return -ENOENT; | 1762 | return -ENOENT; |
1720 | 1763 | ||
@@ -1761,16 +1804,21 @@ ctnetlink_del_expect(struct sock *ctnl, struct sk_buff *skb, | |||
1761 | struct hlist_node *n, *next; | 1804 | struct hlist_node *n, *next; |
1762 | u_int8_t u3 = nfmsg->nfgen_family; | 1805 | u_int8_t u3 = nfmsg->nfgen_family; |
1763 | unsigned int i; | 1806 | unsigned int i; |
1807 | u16 zone; | ||
1764 | int err; | 1808 | int err; |
1765 | 1809 | ||
1766 | if (cda[CTA_EXPECT_TUPLE]) { | 1810 | if (cda[CTA_EXPECT_TUPLE]) { |
1767 | /* delete a single expect by tuple */ | 1811 | /* delete a single expect by tuple */ |
1812 | err = ctnetlink_parse_zone(cda[CTA_EXPECT_ZONE], &zone); | ||
1813 | if (err < 0) | ||
1814 | return err; | ||
1815 | |||
1768 | err = ctnetlink_parse_tuple(cda, &tuple, CTA_EXPECT_TUPLE, u3); | 1816 | err = ctnetlink_parse_tuple(cda, &tuple, CTA_EXPECT_TUPLE, u3); |
1769 | if (err < 0) | 1817 | if (err < 0) |
1770 | return err; | 1818 | return err; |
1771 | 1819 | ||
1772 | /* bump usage count to 2 */ | 1820 | /* bump usage count to 2 */ |
1773 | exp = nf_ct_expect_find_get(net, 0, &tuple); | 1821 | exp = nf_ct_expect_find_get(net, zone, &tuple); |
1774 | if (!exp) | 1822 | if (!exp) |
1775 | return -ENOENT; | 1823 | return -ENOENT; |
1776 | 1824 | ||
@@ -1832,7 +1880,8 @@ ctnetlink_change_expect(struct nf_conntrack_expect *x, | |||
1832 | } | 1880 | } |
1833 | 1881 | ||
1834 | static int | 1882 | static int |
1835 | ctnetlink_create_expect(struct net *net, const struct nlattr * const cda[], | 1883 | ctnetlink_create_expect(struct net *net, u16 zone, |
1884 | const struct nlattr * const cda[], | ||
1836 | u_int8_t u3, | 1885 | u_int8_t u3, |
1837 | u32 pid, int report) | 1886 | u32 pid, int report) |
1838 | { | 1887 | { |
@@ -1855,7 +1904,7 @@ ctnetlink_create_expect(struct net *net, const struct nlattr * const cda[], | |||
1855 | return err; | 1904 | return err; |
1856 | 1905 | ||
1857 | /* Look for master conntrack of this expectation */ | 1906 | /* Look for master conntrack of this expectation */ |
1858 | h = nf_conntrack_find_get(net, 0, &master_tuple); | 1907 | h = nf_conntrack_find_get(net, zone, &master_tuple); |
1859 | if (!h) | 1908 | if (!h) |
1860 | return -ENOENT; | 1909 | return -ENOENT; |
1861 | ct = nf_ct_tuplehash_to_ctrack(h); | 1910 | ct = nf_ct_tuplehash_to_ctrack(h); |
@@ -1900,25 +1949,30 @@ ctnetlink_new_expect(struct sock *ctnl, struct sk_buff *skb, | |||
1900 | struct nf_conntrack_expect *exp; | 1949 | struct nf_conntrack_expect *exp; |
1901 | struct nfgenmsg *nfmsg = nlmsg_data(nlh); | 1950 | struct nfgenmsg *nfmsg = nlmsg_data(nlh); |
1902 | u_int8_t u3 = nfmsg->nfgen_family; | 1951 | u_int8_t u3 = nfmsg->nfgen_family; |
1903 | int err = 0; | 1952 | u16 zone; |
1953 | int err; | ||
1904 | 1954 | ||
1905 | if (!cda[CTA_EXPECT_TUPLE] | 1955 | if (!cda[CTA_EXPECT_TUPLE] |
1906 | || !cda[CTA_EXPECT_MASK] | 1956 | || !cda[CTA_EXPECT_MASK] |
1907 | || !cda[CTA_EXPECT_MASTER]) | 1957 | || !cda[CTA_EXPECT_MASTER]) |
1908 | return -EINVAL; | 1958 | return -EINVAL; |
1909 | 1959 | ||
1960 | err = ctnetlink_parse_zone(cda[CTA_EXPECT_ZONE], &zone); | ||
1961 | if (err < 0) | ||
1962 | return err; | ||
1963 | |||
1910 | err = ctnetlink_parse_tuple(cda, &tuple, CTA_EXPECT_TUPLE, u3); | 1964 | err = ctnetlink_parse_tuple(cda, &tuple, CTA_EXPECT_TUPLE, u3); |
1911 | if (err < 0) | 1965 | if (err < 0) |
1912 | return err; | 1966 | return err; |
1913 | 1967 | ||
1914 | spin_lock_bh(&nf_conntrack_lock); | 1968 | spin_lock_bh(&nf_conntrack_lock); |
1915 | exp = __nf_ct_expect_find(net, 0, &tuple); | 1969 | exp = __nf_ct_expect_find(net, zone, &tuple); |
1916 | 1970 | ||
1917 | if (!exp) { | 1971 | if (!exp) { |
1918 | spin_unlock_bh(&nf_conntrack_lock); | 1972 | spin_unlock_bh(&nf_conntrack_lock); |
1919 | err = -ENOENT; | 1973 | err = -ENOENT; |
1920 | if (nlh->nlmsg_flags & NLM_F_CREATE) { | 1974 | if (nlh->nlmsg_flags & NLM_F_CREATE) { |
1921 | err = ctnetlink_create_expect(net, cda, | 1975 | err = ctnetlink_create_expect(net, zone, cda, |
1922 | u3, | 1976 | u3, |
1923 | NETLINK_CB(skb).pid, | 1977 | NETLINK_CB(skb).pid, |
1924 | nlmsg_report(nlh)); | 1978 | nlmsg_report(nlh)); |