diff options
author | Pablo Neira Ayuso <pablo@netfilter.org> | 2012-06-07 08:19:42 -0400 |
---|---|---|
committer | Pablo Neira Ayuso <pablo@netfilter.org> | 2012-06-16 09:09:15 -0400 |
commit | ae243bee397102c51fbf9db440eca3b077e0e702 (patch) | |
tree | e2320f565fe03c500ed3356b82cc6fbed0a6fe81 /net/netfilter | |
parent | 8c88f87cb27ad09086940bdd3e6955e5325ec89a (diff) |
netfilter: ctnetlink: add CTA_HELP_INFO attribute
This attribute can be used to modify and to dump the internal
protocol information.
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'net/netfilter')
-rw-r--r-- | net/netfilter/nf_conntrack_netlink.c | 23 |
1 files changed, 18 insertions, 5 deletions
diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c index 8be0ab9b475..ae156dff488 100644 --- a/net/netfilter/nf_conntrack_netlink.c +++ b/net/netfilter/nf_conntrack_netlink.c | |||
@@ -902,7 +902,8 @@ static const struct nla_policy help_nla_policy[CTA_HELP_MAX+1] = { | |||
902 | }; | 902 | }; |
903 | 903 | ||
904 | static inline int | 904 | static inline int |
905 | ctnetlink_parse_help(const struct nlattr *attr, char **helper_name) | 905 | ctnetlink_parse_help(const struct nlattr *attr, char **helper_name, |
906 | struct nlattr **helpinfo) | ||
906 | { | 907 | { |
907 | struct nlattr *tb[CTA_HELP_MAX+1]; | 908 | struct nlattr *tb[CTA_HELP_MAX+1]; |
908 | 909 | ||
@@ -913,6 +914,9 @@ ctnetlink_parse_help(const struct nlattr *attr, char **helper_name) | |||
913 | 914 | ||
914 | *helper_name = nla_data(tb[CTA_HELP_NAME]); | 915 | *helper_name = nla_data(tb[CTA_HELP_NAME]); |
915 | 916 | ||
917 | if (tb[CTA_HELP_INFO]) | ||
918 | *helpinfo = tb[CTA_HELP_INFO]; | ||
919 | |||
916 | return 0; | 920 | return 0; |
917 | } | 921 | } |
918 | 922 | ||
@@ -1173,13 +1177,14 @@ ctnetlink_change_helper(struct nf_conn *ct, const struct nlattr * const cda[]) | |||
1173 | struct nf_conntrack_helper *helper; | 1177 | struct nf_conntrack_helper *helper; |
1174 | struct nf_conn_help *help = nfct_help(ct); | 1178 | struct nf_conn_help *help = nfct_help(ct); |
1175 | char *helpname = NULL; | 1179 | char *helpname = NULL; |
1180 | struct nlattr *helpinfo = NULL; | ||
1176 | int err; | 1181 | int err; |
1177 | 1182 | ||
1178 | /* don't change helper of sibling connections */ | 1183 | /* don't change helper of sibling connections */ |
1179 | if (ct->master) | 1184 | if (ct->master) |
1180 | return -EBUSY; | 1185 | return -EBUSY; |
1181 | 1186 | ||
1182 | err = ctnetlink_parse_help(cda[CTA_HELP], &helpname); | 1187 | err = ctnetlink_parse_help(cda[CTA_HELP], &helpname, &helpinfo); |
1183 | if (err < 0) | 1188 | if (err < 0) |
1184 | return err; | 1189 | return err; |
1185 | 1190 | ||
@@ -1214,8 +1219,12 @@ ctnetlink_change_helper(struct nf_conn *ct, const struct nlattr * const cda[]) | |||
1214 | } | 1219 | } |
1215 | 1220 | ||
1216 | if (help) { | 1221 | if (help) { |
1217 | if (help->helper == helper) | 1222 | if (help->helper == helper) { |
1223 | /* update private helper data if allowed. */ | ||
1224 | if (helper->from_nlattr && helpinfo) | ||
1225 | helper->from_nlattr(helpinfo, ct); | ||
1218 | return 0; | 1226 | return 0; |
1227 | } | ||
1219 | if (help->helper) | 1228 | if (help->helper) |
1220 | return -EBUSY; | 1229 | return -EBUSY; |
1221 | /* need to zero data of old helper */ | 1230 | /* need to zero data of old helper */ |
@@ -1411,8 +1420,9 @@ ctnetlink_create_conntrack(struct net *net, u16 zone, | |||
1411 | rcu_read_lock(); | 1420 | rcu_read_lock(); |
1412 | if (cda[CTA_HELP]) { | 1421 | if (cda[CTA_HELP]) { |
1413 | char *helpname = NULL; | 1422 | char *helpname = NULL; |
1414 | 1423 | struct nlattr *helpinfo = NULL; | |
1415 | err = ctnetlink_parse_help(cda[CTA_HELP], &helpname); | 1424 | |
1425 | err = ctnetlink_parse_help(cda[CTA_HELP], &helpname, &helpinfo); | ||
1416 | if (err < 0) | 1426 | if (err < 0) |
1417 | goto err2; | 1427 | goto err2; |
1418 | 1428 | ||
@@ -1446,6 +1456,9 @@ ctnetlink_create_conntrack(struct net *net, u16 zone, | |||
1446 | err = -ENOMEM; | 1456 | err = -ENOMEM; |
1447 | goto err2; | 1457 | goto err2; |
1448 | } | 1458 | } |
1459 | /* set private helper data if allowed. */ | ||
1460 | if (helper->from_nlattr && helpinfo) | ||
1461 | helper->from_nlattr(helpinfo, ct); | ||
1449 | 1462 | ||
1450 | /* not in hash table yet so not strictly necessary */ | 1463 | /* not in hash table yet so not strictly necessary */ |
1451 | RCU_INIT_POINTER(help->helper, helper); | 1464 | RCU_INIT_POINTER(help->helper, helper); |