diff options
-rw-r--r-- | include/linux/netfilter/nfnetlink_conntrack.h | 1 | ||||
-rw-r--r-- | net/netfilter/nf_conntrack_proto_dccp.c | 15 |
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 { | |||
100 | enum ctattr_protoinfo_dccp { | 100 | enum 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 | ||
645 | static const struct nla_policy dccp_nla_policy[CTA_PROTOINFO_DCCP_MAX + 1] = { | 647 | static 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 | ||
649 | static int nlattr_to_dccp(struct nlattr *cda[], struct nf_conn *ct) | 652 | static 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 | } |