aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/netfilter/nfnetlink_conntrack.h1
-rw-r--r--net/netfilter/nf_conntrack_proto_dccp.c15
2 files changed, 15 insertions, 1 deletions
diff --git a/include/linux/netfilter/nfnetlink_conntrack.h b/include/linux/netfilter/nfnetlink_conntrack.h
index 29fe9ea1d346..1a865e48b8eb 100644
--- a/include/linux/netfilter/nfnetlink_conntrack.h
+++ b/include/linux/netfilter/nfnetlink_conntrack.h
@@ -100,6 +100,7 @@ enum ctattr_protoinfo_tcp {
100enum ctattr_protoinfo_dccp { 100enum ctattr_protoinfo_dccp {
101 CTA_PROTOINFO_DCCP_UNSPEC, 101 CTA_PROTOINFO_DCCP_UNSPEC,
102 CTA_PROTOINFO_DCCP_STATE, 102 CTA_PROTOINFO_DCCP_STATE,
103 CTA_PROTOINFO_DCCP_ROLE,
103 __CTA_PROTOINFO_DCCP_MAX, 104 __CTA_PROTOINFO_DCCP_MAX,
104}; 105};
105#define CTA_PROTOINFO_DCCP_MAX (__CTA_PROTOINFO_DCCP_MAX - 1) 106#define CTA_PROTOINFO_DCCP_MAX (__CTA_PROTOINFO_DCCP_MAX - 1)
diff --git a/net/netfilter/nf_conntrack_proto_dccp.c b/net/netfilter/nf_conntrack_proto_dccp.c
index 5411d63f31a5..8e757dd53396 100644
--- a/net/netfilter/nf_conntrack_proto_dccp.c
+++ b/net/netfilter/nf_conntrack_proto_dccp.c
@@ -633,6 +633,8 @@ static int dccp_to_nlattr(struct sk_buff *skb, struct nlattr *nla,
633 if (!nest_parms) 633 if (!nest_parms)
634 goto nla_put_failure; 634 goto nla_put_failure;
635 NLA_PUT_U8(skb, CTA_PROTOINFO_DCCP_STATE, ct->proto.dccp.state); 635 NLA_PUT_U8(skb, CTA_PROTOINFO_DCCP_STATE, ct->proto.dccp.state);
636 NLA_PUT_U8(skb, CTA_PROTOINFO_DCCP_ROLE,
637 ct->proto.dccp.role[IP_CT_DIR_ORIGINAL]);
636 nla_nest_end(skb, nest_parms); 638 nla_nest_end(skb, nest_parms);
637 read_unlock_bh(&dccp_lock); 639 read_unlock_bh(&dccp_lock);
638 return 0; 640 return 0;
@@ -644,6 +646,7 @@ nla_put_failure:
644 646
645static const struct nla_policy dccp_nla_policy[CTA_PROTOINFO_DCCP_MAX + 1] = { 647static const struct nla_policy dccp_nla_policy[CTA_PROTOINFO_DCCP_MAX + 1] = {
646 [CTA_PROTOINFO_DCCP_STATE] = { .type = NLA_U8 }, 648 [CTA_PROTOINFO_DCCP_STATE] = { .type = NLA_U8 },
649 [CTA_PROTOINFO_DCCP_ROLE] = { .type = NLA_U8 },
647}; 650};
648 651
649static int nlattr_to_dccp(struct nlattr *cda[], struct nf_conn *ct) 652static int nlattr_to_dccp(struct nlattr *cda[], struct nf_conn *ct)
@@ -661,11 +664,21 @@ static int nlattr_to_dccp(struct nlattr *cda[], struct nf_conn *ct)
661 return err; 664 return err;
662 665
663 if (!tb[CTA_PROTOINFO_DCCP_STATE] || 666 if (!tb[CTA_PROTOINFO_DCCP_STATE] ||
664 nla_get_u8(tb[CTA_PROTOINFO_DCCP_STATE]) >= CT_DCCP_IGNORE) 667 !tb[CTA_PROTOINFO_DCCP_ROLE] ||
668 nla_get_u8(tb[CTA_PROTOINFO_DCCP_ROLE]) > CT_DCCP_ROLE_MAX ||
669 nla_get_u8(tb[CTA_PROTOINFO_DCCP_STATE]) >= CT_DCCP_IGNORE) {
665 return -EINVAL; 670 return -EINVAL;
671 }
666 672
667 write_lock_bh(&dccp_lock); 673 write_lock_bh(&dccp_lock);
668 ct->proto.dccp.state = nla_get_u8(tb[CTA_PROTOINFO_DCCP_STATE]); 674 ct->proto.dccp.state = nla_get_u8(tb[CTA_PROTOINFO_DCCP_STATE]);
675 if (nla_get_u8(tb[CTA_PROTOINFO_DCCP_ROLE]) == CT_DCCP_ROLE_CLIENT) {
676 ct->proto.dccp.role[IP_CT_DIR_ORIGINAL] = CT_DCCP_ROLE_CLIENT;
677 ct->proto.dccp.role[IP_CT_DIR_REPLY] = CT_DCCP_ROLE_SERVER;
678 } else {
679 ct->proto.dccp.role[IP_CT_DIR_ORIGINAL] = CT_DCCP_ROLE_SERVER;
680 ct->proto.dccp.role[IP_CT_DIR_REPLY] = CT_DCCP_ROLE_CLIENT;
681 }
669 write_unlock_bh(&dccp_lock); 682 write_unlock_bh(&dccp_lock);
670 return 0; 683 return 0;
671} 684}