aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHarald Welte <laforge@netfilter.org>2005-08-09 23:03:40 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2005-08-29 18:39:14 -0400
commit927ccbcc28dceee29dad876982768cca29738564 (patch)
treea5bc50c92c1627e373e3cf9efbaec5c1d3f1b2b7
parentbd9a26b7f2ee7567571bb5b7acc1a256c544a0dd (diff)
[NETFILTER]: attribute count is an attribute of message type, not subsytem
Prior to this patch, every nfnetlink subsystem had to specify it's attribute count. However, in reality the attribute count depends on the message type within the subsystem, not the subsystem itself. This patch moves 'attr_count' from 'struct nfnetlink_subsys' into nfnl_callback to fix this. Signed-off-by: Harald Welte <laforge@netfilter.org> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--include/linux/netfilter/nfnetlink.h4
-rw-r--r--net/ipv4/netfilter/ip_conntrack_netlink.c9
-rw-r--r--net/netfilter/nfnetlink.c20
-rw-r--r--net/netfilter/nfnetlink_log.c5
-rw-r--r--net/netfilter/nfnetlink_queue.c4
5 files changed, 31 insertions, 11 deletions
diff --git a/include/linux/netfilter/nfnetlink.h b/include/linux/netfilter/nfnetlink.h
index 561f9df28808..b0feb2374079 100644
--- a/include/linux/netfilter/nfnetlink.h
+++ b/include/linux/netfilter/nfnetlink.h
@@ -85,9 +85,10 @@ struct nfgenmsg {
85 85
86struct nfnl_callback 86struct nfnl_callback
87{ 87{
88 kernel_cap_t cap_required; /* capabilities required for this msg */
89 int (*call)(struct sock *nl, struct sk_buff *skb, 88 int (*call)(struct sock *nl, struct sk_buff *skb,
90 struct nlmsghdr *nlh, struct nfattr *cda[], int *errp); 89 struct nlmsghdr *nlh, struct nfattr *cda[], int *errp);
90 kernel_cap_t cap_required; /* capabilities required for this msg */
91 u_int16_t attr_count; /* number of nfattr's */
91}; 92};
92 93
93struct nfnetlink_subsystem 94struct nfnetlink_subsystem
@@ -95,7 +96,6 @@ struct nfnetlink_subsystem
95 const char *name; 96 const char *name;
96 __u8 subsys_id; /* nfnetlink subsystem ID */ 97 __u8 subsys_id; /* nfnetlink subsystem ID */
97 __u8 cb_count; /* number of callbacks */ 98 __u8 cb_count; /* number of callbacks */
98 u_int32_t attr_count; /* number of nfattr's */
99 struct nfnl_callback *cb; /* callback for individual types */ 99 struct nfnl_callback *cb; /* callback for individual types */
100}; 100};
101 101
diff --git a/net/ipv4/netfilter/ip_conntrack_netlink.c b/net/ipv4/netfilter/ip_conntrack_netlink.c
index 23f18f6a5535..53d98974dcf0 100644
--- a/net/ipv4/netfilter/ip_conntrack_netlink.c
+++ b/net/ipv4/netfilter/ip_conntrack_netlink.c
@@ -1484,21 +1484,28 @@ static struct notifier_block ctnl_notifier_exp = {
1484 1484
1485static struct nfnl_callback ctnl_cb[IPCTNL_MSG_MAX] = { 1485static struct nfnl_callback ctnl_cb[IPCTNL_MSG_MAX] = {
1486 [IPCTNL_MSG_CT_NEW] = { .call = ctnetlink_new_conntrack, 1486 [IPCTNL_MSG_CT_NEW] = { .call = ctnetlink_new_conntrack,
1487 .attr_count = CTA_MAX,
1487 .cap_required = CAP_NET_ADMIN }, 1488 .cap_required = CAP_NET_ADMIN },
1488 [IPCTNL_MSG_CT_GET] = { .call = ctnetlink_get_conntrack, 1489 [IPCTNL_MSG_CT_GET] = { .call = ctnetlink_get_conntrack,
1490 .attr_count = CTA_MAX,
1489 .cap_required = CAP_NET_ADMIN }, 1491 .cap_required = CAP_NET_ADMIN },
1490 [IPCTNL_MSG_CT_DELETE] = { .call = ctnetlink_del_conntrack, 1492 [IPCTNL_MSG_CT_DELETE] = { .call = ctnetlink_del_conntrack,
1493 .attr_count = CTA_MAX,
1491 .cap_required = CAP_NET_ADMIN }, 1494 .cap_required = CAP_NET_ADMIN },
1492 [IPCTNL_MSG_CT_GET_CTRZERO] = { .call = ctnetlink_get_conntrack, 1495 [IPCTNL_MSG_CT_GET_CTRZERO] = { .call = ctnetlink_get_conntrack,
1496 .attr_count = CTA_MAX,
1493 .cap_required = CAP_NET_ADMIN }, 1497 .cap_required = CAP_NET_ADMIN },
1494}; 1498};
1495 1499
1496static struct nfnl_callback ctnl_exp_cb[IPCTNL_MSG_MAX] = { 1500static struct nfnl_callback ctnl_exp_cb[IPCTNL_MSG_MAX] = {
1497 [IPCTNL_MSG_EXP_GET] = { .call = ctnetlink_get_expect, 1501 [IPCTNL_MSG_EXP_GET] = { .call = ctnetlink_get_expect,
1502 .attr_count = CTA_EXPECT_MAX,
1498 .cap_required = CAP_NET_ADMIN }, 1503 .cap_required = CAP_NET_ADMIN },
1499 [IPCTNL_MSG_EXP_NEW] = { .call = ctnetlink_new_expect, 1504 [IPCTNL_MSG_EXP_NEW] = { .call = ctnetlink_new_expect,
1505 .attr_count = CTA_EXPECT_MAX,
1500 .cap_required = CAP_NET_ADMIN }, 1506 .cap_required = CAP_NET_ADMIN },
1501 [IPCTNL_MSG_EXP_DELETE] = { .call = ctnetlink_del_expect, 1507 [IPCTNL_MSG_EXP_DELETE] = { .call = ctnetlink_del_expect,
1508 .attr_count = CTA_EXPECT_MAX,
1502 .cap_required = CAP_NET_ADMIN }, 1509 .cap_required = CAP_NET_ADMIN },
1503}; 1510};
1504 1511
@@ -1506,7 +1513,6 @@ static struct nfnetlink_subsystem ctnl_subsys = {
1506 .name = "conntrack", 1513 .name = "conntrack",
1507 .subsys_id = NFNL_SUBSYS_CTNETLINK, 1514 .subsys_id = NFNL_SUBSYS_CTNETLINK,
1508 .cb_count = IPCTNL_MSG_MAX, 1515 .cb_count = IPCTNL_MSG_MAX,
1509 .attr_count = CTA_MAX,
1510 .cb = ctnl_cb, 1516 .cb = ctnl_cb,
1511}; 1517};
1512 1518
@@ -1514,7 +1520,6 @@ static struct nfnetlink_subsystem ctnl_exp_subsys = {
1514 .name = "conntrack_expect", 1520 .name = "conntrack_expect",
1515 .subsys_id = NFNL_SUBSYS_CTNETLINK_EXP, 1521 .subsys_id = NFNL_SUBSYS_CTNETLINK_EXP,
1516 .cb_count = IPCTNL_MSG_EXP_MAX, 1522 .cb_count = IPCTNL_MSG_EXP_MAX,
1517 .attr_count = CTA_MAX,
1518 .cb = ctnl_exp_cb, 1523 .cb = ctnl_exp_cb,
1519}; 1524};
1520 1525
diff --git a/net/netfilter/nfnetlink.c b/net/netfilter/nfnetlink.c
index 30b25f47f7cc..578e4fe40945 100644
--- a/net/netfilter/nfnetlink.c
+++ b/net/netfilter/nfnetlink.c
@@ -155,8 +155,18 @@ nfnetlink_check_attributes(struct nfnetlink_subsystem *subsys,
155 struct nlmsghdr *nlh, struct nfattr *cda[]) 155 struct nlmsghdr *nlh, struct nfattr *cda[])
156{ 156{
157 int min_len; 157 int min_len;
158 u_int16_t attr_count;
159 u_int8_t cb_id = NFNL_MSG_TYPE(nlh->nlmsg_type);
158 160
159 memset(cda, 0, sizeof(struct nfattr *) * subsys->attr_count); 161 if (unlikely(cb_id >= subsys->cb_count)) {
162 DEBUGP("msgtype %u >= %u, returning\n",
163 cb_id, subsys->cb_count);
164 return -EINVAL;
165 }
166
167 attr_count = subsys->cb[cb_id].attr_count;
168
169 memset(cda, 0, sizeof(struct nfattr *) * attr_count);
160 170
161 /* check attribute lengths. */ 171 /* check attribute lengths. */
162 min_len = NLMSG_ALIGN(sizeof(struct nfgenmsg)); 172 min_len = NLMSG_ALIGN(sizeof(struct nfgenmsg));
@@ -170,7 +180,7 @@ nfnetlink_check_attributes(struct nfnetlink_subsystem *subsys,
170 while (NFA_OK(attr, attrlen)) { 180 while (NFA_OK(attr, attrlen)) {
171 unsigned flavor = attr->nfa_type; 181 unsigned flavor = attr->nfa_type;
172 if (flavor) { 182 if (flavor) {
173 if (flavor > subsys->attr_count) 183 if (flavor > attr_count)
174 return -EINVAL; 184 return -EINVAL;
175 cda[flavor - 1] = attr; 185 cda[flavor - 1] = attr;
176 } 186 }
@@ -256,9 +266,11 @@ static inline int nfnetlink_rcv_msg(struct sk_buff *skb,
256 } 266 }
257 267
258 { 268 {
259 struct nfattr *cda[ss->attr_count]; 269 u_int16_t attr_count =
270 ss->cb[NFNL_MSG_TYPE(nlh->nlmsg_type)].attr_count;
271 struct nfattr *cda[attr_count];
260 272
261 memset(cda, 0, ss->attr_count*sizeof(struct nfattr *)); 273 memset(cda, 0, sizeof(struct nfattr *) * attr_count);
262 274
263 err = nfnetlink_check_attributes(ss, nlh, cda); 275 err = nfnetlink_check_attributes(ss, nlh, cda);
264 if (err < 0) 276 if (err < 0)
diff --git a/net/netfilter/nfnetlink_log.c b/net/netfilter/nfnetlink_log.c
index f41045e385ae..1750f0d6e4de 100644
--- a/net/netfilter/nfnetlink_log.c
+++ b/net/netfilter/nfnetlink_log.c
@@ -805,8 +805,10 @@ out_put:
805 805
806static struct nfnl_callback nfulnl_cb[NFULNL_MSG_MAX] = { 806static struct nfnl_callback nfulnl_cb[NFULNL_MSG_MAX] = {
807 [NFULNL_MSG_PACKET] = { .call = nfulnl_recv_unsupp, 807 [NFULNL_MSG_PACKET] = { .call = nfulnl_recv_unsupp,
808 .cap_required = CAP_NET_ADMIN }, 808 .attr_count = NFULA_MAX,
809 .cap_required = CAP_NET_ADMIN, },
809 [NFULNL_MSG_CONFIG] = { .call = nfulnl_recv_config, 810 [NFULNL_MSG_CONFIG] = { .call = nfulnl_recv_config,
811 .attr_count = NFULA_CFG_MAX,
810 .cap_required = CAP_NET_ADMIN }, 812 .cap_required = CAP_NET_ADMIN },
811}; 813};
812 814
@@ -814,7 +816,6 @@ static struct nfnetlink_subsystem nfulnl_subsys = {
814 .name = "log", 816 .name = "log",
815 .subsys_id = NFNL_SUBSYS_ULOG, 817 .subsys_id = NFNL_SUBSYS_ULOG,
816 .cb_count = NFULNL_MSG_MAX, 818 .cb_count = NFULNL_MSG_MAX,
817 .attr_count = NFULA_MAX,
818 .cb = nfulnl_cb, 819 .cb = nfulnl_cb,
819}; 820};
820 821
diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c
index d7b0330d64b4..04323ee1eb8d 100644
--- a/net/netfilter/nfnetlink_queue.c
+++ b/net/netfilter/nfnetlink_queue.c
@@ -877,10 +877,13 @@ out_put:
877 877
878static struct nfnl_callback nfqnl_cb[NFQNL_MSG_MAX] = { 878static struct nfnl_callback nfqnl_cb[NFQNL_MSG_MAX] = {
879 [NFQNL_MSG_PACKET] = { .call = nfqnl_recv_unsupp, 879 [NFQNL_MSG_PACKET] = { .call = nfqnl_recv_unsupp,
880 .attr_count = NFQA_MAX,
880 .cap_required = CAP_NET_ADMIN }, 881 .cap_required = CAP_NET_ADMIN },
881 [NFQNL_MSG_VERDICT] = { .call = nfqnl_recv_verdict, 882 [NFQNL_MSG_VERDICT] = { .call = nfqnl_recv_verdict,
883 .attr_count = NFQA_MAX,
882 .cap_required = CAP_NET_ADMIN }, 884 .cap_required = CAP_NET_ADMIN },
883 [NFQNL_MSG_CONFIG] = { .call = nfqnl_recv_config, 885 [NFQNL_MSG_CONFIG] = { .call = nfqnl_recv_config,
886 .attr_count = NFQA_CFG_MAX,
884 .cap_required = CAP_NET_ADMIN }, 887 .cap_required = CAP_NET_ADMIN },
885}; 888};
886 889
@@ -888,7 +891,6 @@ static struct nfnetlink_subsystem nfqnl_subsys = {
888 .name = "nf_queue", 891 .name = "nf_queue",
889 .subsys_id = NFNL_SUBSYS_QUEUE, 892 .subsys_id = NFNL_SUBSYS_QUEUE,
890 .cb_count = NFQNL_MSG_MAX, 893 .cb_count = NFQNL_MSG_MAX,
891 .attr_count = NFQA_MAX,
892 .cb = nfqnl_cb, 894 .cb = nfqnl_cb,
893}; 895};
894 896