diff options
Diffstat (limited to 'net')
-rw-r--r-- | net/ipv4/netfilter/ip_conntrack_netlink.c | 37 |
1 files changed, 37 insertions, 0 deletions
diff --git a/net/ipv4/netfilter/ip_conntrack_netlink.c b/net/ipv4/netfilter/ip_conntrack_netlink.c index 06ed91ee8ace..166e6069f121 100644 --- a/net/ipv4/netfilter/ip_conntrack_netlink.c +++ b/net/ipv4/netfilter/ip_conntrack_netlink.c | |||
@@ -949,6 +949,31 @@ ctnetlink_change_timeout(struct ip_conntrack *ct, struct nfattr *cda[]) | |||
949 | return 0; | 949 | return 0; |
950 | } | 950 | } |
951 | 951 | ||
952 | static inline int | ||
953 | ctnetlink_change_protoinfo(struct ip_conntrack *ct, struct nfattr *cda[]) | ||
954 | { | ||
955 | struct nfattr *tb[CTA_PROTOINFO_MAX], *attr = cda[CTA_PROTOINFO-1]; | ||
956 | struct ip_conntrack_protocol *proto; | ||
957 | u_int16_t npt = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum; | ||
958 | int err = 0; | ||
959 | |||
960 | if (nfattr_parse_nested(tb, CTA_PROTOINFO_MAX, attr) < 0) | ||
961 | goto nfattr_failure; | ||
962 | |||
963 | proto = ip_conntrack_proto_find_get(npt); | ||
964 | if (!proto) | ||
965 | return -EINVAL; | ||
966 | |||
967 | if (proto->from_nfattr) | ||
968 | err = proto->from_nfattr(tb, ct); | ||
969 | ip_conntrack_proto_put(proto); | ||
970 | |||
971 | return err; | ||
972 | |||
973 | nfattr_failure: | ||
974 | return -ENOMEM; | ||
975 | } | ||
976 | |||
952 | static int | 977 | static int |
953 | ctnetlink_change_conntrack(struct ip_conntrack *ct, struct nfattr *cda[]) | 978 | ctnetlink_change_conntrack(struct ip_conntrack *ct, struct nfattr *cda[]) |
954 | { | 979 | { |
@@ -974,6 +999,12 @@ ctnetlink_change_conntrack(struct ip_conntrack *ct, struct nfattr *cda[]) | |||
974 | return err; | 999 | return err; |
975 | } | 1000 | } |
976 | 1001 | ||
1002 | if (cda[CTA_PROTOINFO-1]) { | ||
1003 | err = ctnetlink_change_protoinfo(ct, cda); | ||
1004 | if (err < 0) | ||
1005 | return err; | ||
1006 | } | ||
1007 | |||
977 | DEBUGP("all done\n"); | 1008 | DEBUGP("all done\n"); |
978 | return 0; | 1009 | return 0; |
979 | } | 1010 | } |
@@ -1003,6 +1034,12 @@ ctnetlink_create_conntrack(struct nfattr *cda[], | |||
1003 | if (err < 0) | 1034 | if (err < 0) |
1004 | goto err; | 1035 | goto err; |
1005 | 1036 | ||
1037 | if (cda[CTA_PROTOINFO-1]) { | ||
1038 | err = ctnetlink_change_protoinfo(ct, cda); | ||
1039 | if (err < 0) | ||
1040 | return err; | ||
1041 | } | ||
1042 | |||
1006 | ct->helper = ip_conntrack_helper_find_get(rtuple); | 1043 | ct->helper = ip_conntrack_helper_find_get(rtuple); |
1007 | 1044 | ||
1008 | add_timer(&ct->timeout); | 1045 | add_timer(&ct->timeout); |