提交 ae243bee 编写于 作者: P Pablo Neira Ayuso

netfilter: ctnetlink: add CTA_HELP_INFO attribute

This attribute can be used to modify and to dump the internal
protocol information.
Signed-off-by: NPablo Neira Ayuso <pablo@netfilter.org>
上级 8c88f87c
...@@ -191,6 +191,7 @@ enum ctattr_expect_nat { ...@@ -191,6 +191,7 @@ enum ctattr_expect_nat {
enum ctattr_help { enum ctattr_help {
CTA_HELP_UNSPEC, CTA_HELP_UNSPEC,
CTA_HELP_NAME, CTA_HELP_NAME,
CTA_HELP_INFO,
__CTA_HELP_MAX __CTA_HELP_MAX
}; };
#define CTA_HELP_MAX (__CTA_HELP_MAX - 1) #define CTA_HELP_MAX (__CTA_HELP_MAX - 1)
......
...@@ -39,6 +39,7 @@ struct nf_conntrack_helper { ...@@ -39,6 +39,7 @@ struct nf_conntrack_helper {
void (*destroy)(struct nf_conn *ct); void (*destroy)(struct nf_conn *ct);
int (*from_nlattr)(struct nlattr *attr, struct nf_conn *ct);
int (*to_nlattr)(struct sk_buff *skb, const struct nf_conn *ct); int (*to_nlattr)(struct sk_buff *skb, const struct nf_conn *ct);
unsigned int expect_class_max; unsigned int expect_class_max;
}; };
......
...@@ -902,7 +902,8 @@ static const struct nla_policy help_nla_policy[CTA_HELP_MAX+1] = { ...@@ -902,7 +902,8 @@ static const struct nla_policy help_nla_policy[CTA_HELP_MAX+1] = {
}; };
static inline int static inline int
ctnetlink_parse_help(const struct nlattr *attr, char **helper_name) ctnetlink_parse_help(const struct nlattr *attr, char **helper_name,
struct nlattr **helpinfo)
{ {
struct nlattr *tb[CTA_HELP_MAX+1]; struct nlattr *tb[CTA_HELP_MAX+1];
...@@ -913,6 +914,9 @@ ctnetlink_parse_help(const struct nlattr *attr, char **helper_name) ...@@ -913,6 +914,9 @@ ctnetlink_parse_help(const struct nlattr *attr, char **helper_name)
*helper_name = nla_data(tb[CTA_HELP_NAME]); *helper_name = nla_data(tb[CTA_HELP_NAME]);
if (tb[CTA_HELP_INFO])
*helpinfo = tb[CTA_HELP_INFO];
return 0; return 0;
} }
...@@ -1173,13 +1177,14 @@ ctnetlink_change_helper(struct nf_conn *ct, const struct nlattr * const cda[]) ...@@ -1173,13 +1177,14 @@ ctnetlink_change_helper(struct nf_conn *ct, const struct nlattr * const cda[])
struct nf_conntrack_helper *helper; struct nf_conntrack_helper *helper;
struct nf_conn_help *help = nfct_help(ct); struct nf_conn_help *help = nfct_help(ct);
char *helpname = NULL; char *helpname = NULL;
struct nlattr *helpinfo = NULL;
int err; int err;
/* don't change helper of sibling connections */ /* don't change helper of sibling connections */
if (ct->master) if (ct->master)
return -EBUSY; return -EBUSY;
err = ctnetlink_parse_help(cda[CTA_HELP], &helpname); err = ctnetlink_parse_help(cda[CTA_HELP], &helpname, &helpinfo);
if (err < 0) if (err < 0)
return err; return err;
...@@ -1214,8 +1219,12 @@ ctnetlink_change_helper(struct nf_conn *ct, const struct nlattr * const cda[]) ...@@ -1214,8 +1219,12 @@ ctnetlink_change_helper(struct nf_conn *ct, const struct nlattr * const cda[])
} }
if (help) { if (help) {
if (help->helper == helper) if (help->helper == helper) {
/* update private helper data if allowed. */
if (helper->from_nlattr && helpinfo)
helper->from_nlattr(helpinfo, ct);
return 0; return 0;
}
if (help->helper) if (help->helper)
return -EBUSY; return -EBUSY;
/* need to zero data of old helper */ /* need to zero data of old helper */
...@@ -1411,8 +1420,9 @@ ctnetlink_create_conntrack(struct net *net, u16 zone, ...@@ -1411,8 +1420,9 @@ ctnetlink_create_conntrack(struct net *net, u16 zone,
rcu_read_lock(); rcu_read_lock();
if (cda[CTA_HELP]) { if (cda[CTA_HELP]) {
char *helpname = NULL; char *helpname = NULL;
struct nlattr *helpinfo = NULL;
err = ctnetlink_parse_help(cda[CTA_HELP], &helpname);
err = ctnetlink_parse_help(cda[CTA_HELP], &helpname, &helpinfo);
if (err < 0) if (err < 0)
goto err2; goto err2;
...@@ -1446,6 +1456,9 @@ ctnetlink_create_conntrack(struct net *net, u16 zone, ...@@ -1446,6 +1456,9 @@ ctnetlink_create_conntrack(struct net *net, u16 zone,
err = -ENOMEM; err = -ENOMEM;
goto err2; goto err2;
} }
/* set private helper data if allowed. */
if (helper->from_nlattr && helpinfo)
helper->from_nlattr(helpinfo, ct);
/* not in hash table yet so not strictly necessary */ /* not in hash table yet so not strictly necessary */
RCU_INIT_POINTER(help->helper, helper); RCU_INIT_POINTER(help->helper, helper);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册