Index: netfilter-2.6.14/net/ipv4/netfilter/ip_conntrack_netlink.c =================================================================== --- netfilter-2.6.14.orig/net/ipv4/netfilter/ip_conntrack_netlink.c 2005-08-13 10:45:09.000000000 +0200 +++ netfilter-2.6.14/net/ipv4/netfilter/ip_conntrack_netlink.c 2005-08-13 10:51:34.000000000 +0200 @@ -948,6 +948,36 @@ return 0; } +static inline int +ctnetlink_change_protoinfo(struct ip_conntrack *ct, struct nfattr *cda[]) +{ + struct nfattr *tb[CTA_PROTOINFO_MAX], *attr = cda[CTA_PROTOINFO-1]; + struct ip_conntrack_protocol *proto; + u_int16_t npt = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum; + int err; + + if (nfattr_parse_nested(tb, CTA_PROTOINFO_MAX, attr) < 0) + goto nfattr_failure; + + proto = ip_conntrack_proto_find_get(npt); + if (!proto) + return -EINVAL; + + if (proto->from_nfattr) { + err = proto->from_nfattr(tb, ct); + if (err < 0) { + ip_conntrack_proto_put(proto); + return -EINVAL; + } + } + ip_conntrack_proto_put(proto); + + return 0; + +nfattr_failure: + return -1; +} + static int ctnetlink_change_conntrack(struct ip_conntrack *ct, struct nfattr *cda[]) { @@ -973,6 +1003,12 @@ return err; } + if (cda[CTA_PROTOINFO-1]) { + err = ctnetlink_change_protoinfo(ct, cda); + if (err < 0) + return err; + } + DEBUGP("all done\n"); return 0; } @@ -1002,6 +1038,12 @@ if (err < 0) goto err; + if (cda[CTA_PROTOINFO-1]) { + err = ctnetlink_change_protoinfo(ct, cda); + if (err < 0) + return err; + } + ct->helper = ip_conntrack_helper_find_get(rtuple); add_timer(&ct->timeout);