static inline int ctnetlink_dump_protoinfo(struct sk_buff *skb, const struct nf_conn *ct) { struct nf_conntrack_protocol *proto = nf_ct_proto_find_get(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.l3num, ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum); struct nfattr *nest_proto; int ret; if (!proto->to_nfattr) { nf_ct_proto_put(proto); return 0; } nest_proto = NFA_NEST(skb, CTA_PROTOINFO); ret = proto->to_nfattr(skb, nest_proto, ct); nf_ct_proto_put(proto); NFA_NEST_END(skb, nest_proto); return ret; nfattr_failure: return -1; }
static inline int ctnetlink_dump_tuples(struct sk_buff *skb, const struct nf_conntrack_tuple *tuple) { int ret; struct nf_conntrack_l3proto *l3proto; struct nf_conntrack_protocol *proto; l3proto = nf_ct_l3proto_find_get(tuple->src.l3num); ret = ctnetlink_dump_tuples_ip(skb, tuple, l3proto); nf_ct_l3proto_put(l3proto); if (unlikely(ret < 0)) return ret; proto = nf_ct_proto_find_get(tuple->src.l3num, tuple->dst.protonum); ret = ctnetlink_dump_tuples_proto(skb, tuple, proto); nf_ct_proto_put(proto); return ret; }
static inline int ctnetlink_dump_tuples_proto(struct sk_buff *skb, const struct nf_conntrack_tuple *tuple) { struct nf_conntrack_protocol *proto; int ret = 0; NFA_PUT(skb, CTA_PROTO_NUM, sizeof(u_int8_t), &tuple->dst.protonum); /* If no protocol helper is found, this function will return the * generic protocol helper, so proto won't *ever* be NULL */ proto = nf_ct_proto_find_get(tuple->src.l3num, tuple->dst.protonum); if (likely(proto->tuple_to_nfattr)) ret = proto->tuple_to_nfattr(skb, tuple); nf_ct_proto_put(proto); return ret; nfattr_failure: return -1; }