aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
Diffstat (limited to 'net')
-rw-r--r--net/openvswitch/conntrack.c40
-rw-r--r--net/openvswitch/conntrack.h8
-rw-r--r--net/openvswitch/flow.h14
-rw-r--r--net/openvswitch/flow_netlink.c11
4 files changed, 39 insertions, 34 deletions
diff --git a/net/openvswitch/conntrack.c b/net/openvswitch/conntrack.c
index 8b15bab70583..c2d452eab0c5 100644
--- a/net/openvswitch/conntrack.c
+++ b/net/openvswitch/conntrack.c
@@ -152,7 +152,7 @@ static void __ovs_ct_update_key_orig_tp(struct sw_flow_key *key,
152 const struct nf_conntrack_tuple *orig, 152 const struct nf_conntrack_tuple *orig,
153 u8 icmp_proto) 153 u8 icmp_proto)
154{ 154{
155 key->ct.orig_proto = orig->dst.protonum; 155 key->ct_orig_proto = orig->dst.protonum;
156 if (orig->dst.protonum == icmp_proto) { 156 if (orig->dst.protonum == icmp_proto) {
157 key->ct.orig_tp.src = htons(orig->dst.u.icmp.type); 157 key->ct.orig_tp.src = htons(orig->dst.u.icmp.type);
158 key->ct.orig_tp.dst = htons(orig->dst.u.icmp.code); 158 key->ct.orig_tp.dst = htons(orig->dst.u.icmp.code);
@@ -166,8 +166,8 @@ static void __ovs_ct_update_key(struct sw_flow_key *key, u8 state,
166 const struct nf_conntrack_zone *zone, 166 const struct nf_conntrack_zone *zone,
167 const struct nf_conn *ct) 167 const struct nf_conn *ct)
168{ 168{
169 key->ct.state = state; 169 key->ct_state = state;
170 key->ct.zone = zone->id; 170 key->ct_zone = zone->id;
171 key->ct.mark = ovs_ct_get_mark(ct); 171 key->ct.mark = ovs_ct_get_mark(ct);
172 ovs_ct_get_labels(ct, &key->ct.labels); 172 ovs_ct_get_labels(ct, &key->ct.labels);
173 173
@@ -195,10 +195,10 @@ static void __ovs_ct_update_key(struct sw_flow_key *key, u8 state,
195 return; 195 return;
196 } 196 }
197 } 197 }
198 /* Clear 'ct.orig_proto' to mark the non-existence of conntrack 198 /* Clear 'ct_orig_proto' to mark the non-existence of conntrack
199 * original direction key fields. 199 * original direction key fields.
200 */ 200 */
201 key->ct.orig_proto = 0; 201 key->ct_orig_proto = 0;
202} 202}
203 203
204/* Update 'key' based on skb->_nfct. If 'post_ct' is true, then OVS has 204/* Update 'key' based on skb->_nfct. If 'post_ct' is true, then OVS has
@@ -228,7 +228,7 @@ static void ovs_ct_update_key(const struct sk_buff *skb,
228 if (ct->master) 228 if (ct->master)
229 state |= OVS_CS_F_RELATED; 229 state |= OVS_CS_F_RELATED;
230 if (keep_nat_flags) { 230 if (keep_nat_flags) {
231 state |= key->ct.state & OVS_CS_F_NAT_MASK; 231 state |= key->ct_state & OVS_CS_F_NAT_MASK;
232 } else { 232 } else {
233 if (ct->status & IPS_SRC_NAT) 233 if (ct->status & IPS_SRC_NAT)
234 state |= OVS_CS_F_SRC_NAT; 234 state |= OVS_CS_F_SRC_NAT;
@@ -259,11 +259,11 @@ void ovs_ct_fill_key(const struct sk_buff *skb, struct sw_flow_key *key)
259int ovs_ct_put_key(const struct sw_flow_key *swkey, 259int ovs_ct_put_key(const struct sw_flow_key *swkey,
260 const struct sw_flow_key *output, struct sk_buff *skb) 260 const struct sw_flow_key *output, struct sk_buff *skb)
261{ 261{
262 if (nla_put_u32(skb, OVS_KEY_ATTR_CT_STATE, output->ct.state)) 262 if (nla_put_u32(skb, OVS_KEY_ATTR_CT_STATE, output->ct_state))
263 return -EMSGSIZE; 263 return -EMSGSIZE;
264 264
265 if (IS_ENABLED(CONFIG_NF_CONNTRACK_ZONES) && 265 if (IS_ENABLED(CONFIG_NF_CONNTRACK_ZONES) &&
266 nla_put_u16(skb, OVS_KEY_ATTR_CT_ZONE, output->ct.zone)) 266 nla_put_u16(skb, OVS_KEY_ATTR_CT_ZONE, output->ct_zone))
267 return -EMSGSIZE; 267 return -EMSGSIZE;
268 268
269 if (IS_ENABLED(CONFIG_NF_CONNTRACK_MARK) && 269 if (IS_ENABLED(CONFIG_NF_CONNTRACK_MARK) &&
@@ -275,14 +275,14 @@ int ovs_ct_put_key(const struct sw_flow_key *swkey,
275 &output->ct.labels)) 275 &output->ct.labels))
276 return -EMSGSIZE; 276 return -EMSGSIZE;
277 277
278 if (swkey->ct.orig_proto) { 278 if (swkey->ct_orig_proto) {
279 if (swkey->eth.type == htons(ETH_P_IP)) { 279 if (swkey->eth.type == htons(ETH_P_IP)) {
280 struct ovs_key_ct_tuple_ipv4 orig = { 280 struct ovs_key_ct_tuple_ipv4 orig = {
281 output->ipv4.ct_orig.src, 281 output->ipv4.ct_orig.src,
282 output->ipv4.ct_orig.dst, 282 output->ipv4.ct_orig.dst,
283 output->ct.orig_tp.src, 283 output->ct.orig_tp.src,
284 output->ct.orig_tp.dst, 284 output->ct.orig_tp.dst,
285 output->ct.orig_proto, 285 output->ct_orig_proto,
286 }; 286 };
287 if (nla_put(skb, OVS_KEY_ATTR_CT_ORIG_TUPLE_IPV4, 287 if (nla_put(skb, OVS_KEY_ATTR_CT_ORIG_TUPLE_IPV4,
288 sizeof(orig), &orig)) 288 sizeof(orig), &orig))
@@ -293,7 +293,7 @@ int ovs_ct_put_key(const struct sw_flow_key *swkey,
293 IN6_ADDR_INITIALIZER(output->ipv6.ct_orig.dst), 293 IN6_ADDR_INITIALIZER(output->ipv6.ct_orig.dst),
294 output->ct.orig_tp.src, 294 output->ct.orig_tp.src,
295 output->ct.orig_tp.dst, 295 output->ct.orig_tp.dst,
296 output->ct.orig_proto, 296 output->ct_orig_proto,
297 }; 297 };
298 if (nla_put(skb, OVS_KEY_ATTR_CT_ORIG_TUPLE_IPV6, 298 if (nla_put(skb, OVS_KEY_ATTR_CT_ORIG_TUPLE_IPV6,
299 sizeof(orig), &orig)) 299 sizeof(orig), &orig))
@@ -612,11 +612,11 @@ static bool skb_nfct_cached(struct net *net,
612 * due to an upcall. If the connection was not confirmed, it is not 612 * due to an upcall. If the connection was not confirmed, it is not
613 * cached and needs to be run through conntrack again. 613 * cached and needs to be run through conntrack again.
614 */ 614 */
615 if (!ct && key->ct.state & OVS_CS_F_TRACKED && 615 if (!ct && key->ct_state & OVS_CS_F_TRACKED &&
616 !(key->ct.state & OVS_CS_F_INVALID) && 616 !(key->ct_state & OVS_CS_F_INVALID) &&
617 key->ct.zone == info->zone.id) { 617 key->ct_zone == info->zone.id) {
618 ct = ovs_ct_find_existing(net, &info->zone, info->family, skb, 618 ct = ovs_ct_find_existing(net, &info->zone, info->family, skb,
619 !!(key->ct.state 619 !!(key->ct_state
620 & OVS_CS_F_NAT_MASK)); 620 & OVS_CS_F_NAT_MASK));
621 if (ct) 621 if (ct)
622 nf_ct_get(skb, &ctinfo); 622 nf_ct_get(skb, &ctinfo);
@@ -740,7 +740,7 @@ static void ovs_nat_update_key(struct sw_flow_key *key,
740 if (maniptype == NF_NAT_MANIP_SRC) { 740 if (maniptype == NF_NAT_MANIP_SRC) {
741 __be16 src; 741 __be16 src;
742 742
743 key->ct.state |= OVS_CS_F_SRC_NAT; 743 key->ct_state |= OVS_CS_F_SRC_NAT;
744 if (key->eth.type == htons(ETH_P_IP)) 744 if (key->eth.type == htons(ETH_P_IP))
745 key->ipv4.addr.src = ip_hdr(skb)->saddr; 745 key->ipv4.addr.src = ip_hdr(skb)->saddr;
746 else if (key->eth.type == htons(ETH_P_IPV6)) 746 else if (key->eth.type == htons(ETH_P_IPV6))
@@ -762,7 +762,7 @@ static void ovs_nat_update_key(struct sw_flow_key *key,
762 } else { 762 } else {
763 __be16 dst; 763 __be16 dst;
764 764
765 key->ct.state |= OVS_CS_F_DST_NAT; 765 key->ct_state |= OVS_CS_F_DST_NAT;
766 if (key->eth.type == htons(ETH_P_IP)) 766 if (key->eth.type == htons(ETH_P_IP))
767 key->ipv4.addr.dst = ip_hdr(skb)->daddr; 767 key->ipv4.addr.dst = ip_hdr(skb)->daddr;
768 else if (key->eth.type == htons(ETH_P_IPV6)) 768 else if (key->eth.type == htons(ETH_P_IPV6))
@@ -886,7 +886,7 @@ static int __ovs_ct_lookup(struct net *net, struct sw_flow_key *key,
886 * NAT after the nf_conntrack_in() call. We can actually clear 886 * NAT after the nf_conntrack_in() call. We can actually clear
887 * the whole state, as it will be re-initialized below. 887 * the whole state, as it will be re-initialized below.
888 */ 888 */
889 key->ct.state = 0; 889 key->ct_state = 0;
890 890
891 /* Update the key, but keep the NAT flags. */ 891 /* Update the key, but keep the NAT flags. */
892 ovs_ct_update_key(skb, info, key, true, true); 892 ovs_ct_update_key(skb, info, key, true, true);
@@ -902,9 +902,9 @@ static int __ovs_ct_lookup(struct net *net, struct sw_flow_key *key,
902 * 902 *
903 * NAT will be done only if the CT action has NAT, and only 903 * NAT will be done only if the CT action has NAT, and only
904 * once per packet (per zone), as guarded by the NAT bits in 904 * once per packet (per zone), as guarded by the NAT bits in
905 * the key->ct.state. 905 * the key->ct_state.
906 */ 906 */
907 if (info->nat && !(key->ct.state & OVS_CS_F_NAT_MASK) && 907 if (info->nat && !(key->ct_state & OVS_CS_F_NAT_MASK) &&
908 (nf_ct_is_confirmed(ct) || info->commit) && 908 (nf_ct_is_confirmed(ct) || info->commit) &&
909 ovs_ct_nat(net, key, info, skb, ct, ctinfo) != NF_ACCEPT) { 909 ovs_ct_nat(net, key, info, skb, ct, ctinfo) != NF_ACCEPT) {
910 return -EINVAL; 910 return -EINVAL;
diff --git a/net/openvswitch/conntrack.h b/net/openvswitch/conntrack.h
index 9e92445dc092..bc7efd1867ab 100644
--- a/net/openvswitch/conntrack.h
+++ b/net/openvswitch/conntrack.h
@@ -76,14 +76,14 @@ static inline int ovs_ct_execute(struct net *net, struct sk_buff *skb,
76static inline void ovs_ct_fill_key(const struct sk_buff *skb, 76static inline void ovs_ct_fill_key(const struct sk_buff *skb,
77 struct sw_flow_key *key) 77 struct sw_flow_key *key)
78{ 78{
79 key->ct.state = 0; 79 key->ct_state = 0;
80 key->ct.zone = 0; 80 key->ct_zone = 0;
81 key->ct.mark = 0; 81 key->ct.mark = 0;
82 memset(&key->ct.labels, 0, sizeof(key->ct.labels)); 82 memset(&key->ct.labels, 0, sizeof(key->ct.labels));
83 /* Clear 'ct.orig_proto' to mark the non-existence of original 83 /* Clear 'ct_orig_proto' to mark the non-existence of original
84 * direction key fields. 84 * direction key fields.
85 */ 85 */
86 key->ct.orig_proto = 0; 86 key->ct_orig_proto = 0;
87} 87}
88 88
89static inline int ovs_ct_put_key(const struct sw_flow_key *swkey, 89static inline int ovs_ct_put_key(const struct sw_flow_key *swkey,
diff --git a/net/openvswitch/flow.h b/net/openvswitch/flow.h
index 76e05b25f030..a9bc1c875965 100644
--- a/net/openvswitch/flow.h
+++ b/net/openvswitch/flow.h
@@ -85,6 +85,11 @@ struct sw_flow_key {
85 struct vlan_head cvlan; 85 struct vlan_head cvlan;
86 __be16 type; /* Ethernet frame type. */ 86 __be16 type; /* Ethernet frame type. */
87 } eth; 87 } eth;
88 /* Filling a hole of two bytes. */
89 u8 ct_state;
90 u8 ct_orig_proto; /* CT original direction tuple IP
91 * protocol.
92 */
88 union { 93 union {
89 struct { 94 struct {
90 __be32 top_lse; /* top label stack entry */ 95 __be32 top_lse; /* top label stack entry */
@@ -96,6 +101,7 @@ struct sw_flow_key {
96 u8 frag; /* One of OVS_FRAG_TYPE_*. */ 101 u8 frag; /* One of OVS_FRAG_TYPE_*. */
97 } ip; 102 } ip;
98 }; 103 };
104 u16 ct_zone; /* Conntrack zone. */
99 struct { 105 struct {
100 __be16 src; /* TCP/UDP/SCTP source port. */ 106 __be16 src; /* TCP/UDP/SCTP source port. */
101 __be16 dst; /* TCP/UDP/SCTP destination port. */ 107 __be16 dst; /* TCP/UDP/SCTP destination port. */
@@ -138,16 +144,12 @@ struct sw_flow_key {
138 } ipv6; 144 } ipv6;
139 }; 145 };
140 struct { 146 struct {
141 /* Connection tracking fields. */ 147 /* Connection tracking fields not packed above. */
142 u8 state;
143 u8 orig_proto; /* CT orig tuple IP protocol. */
144 u16 zone;
145 u32 mark;
146 struct { 148 struct {
147 __be16 src; /* CT orig tuple tp src port. */ 149 __be16 src; /* CT orig tuple tp src port. */
148 __be16 dst; /* CT orig tuple tp dst port. */ 150 __be16 dst; /* CT orig tuple tp dst port. */
149 } orig_tp; 151 } orig_tp;
150 152 u32 mark;
151 struct ovs_key_ct_labels labels; 153 struct ovs_key_ct_labels labels;
152 } ct; 154 } ct;
153 155
diff --git a/net/openvswitch/flow_netlink.c b/net/openvswitch/flow_netlink.c
index 989f38f120bb..6f5fa50f716d 100644
--- a/net/openvswitch/flow_netlink.c
+++ b/net/openvswitch/flow_netlink.c
@@ -1072,14 +1072,14 @@ static int metadata_from_nlattrs(struct net *net, struct sw_flow_match *match,
1072 return -EINVAL; 1072 return -EINVAL;
1073 } 1073 }
1074 1074
1075 SW_FLOW_KEY_PUT(match, ct.state, ct_state, is_mask); 1075 SW_FLOW_KEY_PUT(match, ct_state, ct_state, is_mask);
1076 *attrs &= ~(1ULL << OVS_KEY_ATTR_CT_STATE); 1076 *attrs &= ~(1ULL << OVS_KEY_ATTR_CT_STATE);
1077 } 1077 }
1078 if (*attrs & (1 << OVS_KEY_ATTR_CT_ZONE) && 1078 if (*attrs & (1 << OVS_KEY_ATTR_CT_ZONE) &&
1079 ovs_ct_verify(net, OVS_KEY_ATTR_CT_ZONE)) { 1079 ovs_ct_verify(net, OVS_KEY_ATTR_CT_ZONE)) {
1080 u16 ct_zone = nla_get_u16(a[OVS_KEY_ATTR_CT_ZONE]); 1080 u16 ct_zone = nla_get_u16(a[OVS_KEY_ATTR_CT_ZONE]);
1081 1081
1082 SW_FLOW_KEY_PUT(match, ct.zone, ct_zone, is_mask); 1082 SW_FLOW_KEY_PUT(match, ct_zone, ct_zone, is_mask);
1083 *attrs &= ~(1ULL << OVS_KEY_ATTR_CT_ZONE); 1083 *attrs &= ~(1ULL << OVS_KEY_ATTR_CT_ZONE);
1084 } 1084 }
1085 if (*attrs & (1 << OVS_KEY_ATTR_CT_MARK) && 1085 if (*attrs & (1 << OVS_KEY_ATTR_CT_MARK) &&
@@ -1107,7 +1107,7 @@ static int metadata_from_nlattrs(struct net *net, struct sw_flow_match *match,
1107 SW_FLOW_KEY_PUT(match, ipv4.ct_orig.dst, ct->ipv4_dst, is_mask); 1107 SW_FLOW_KEY_PUT(match, ipv4.ct_orig.dst, ct->ipv4_dst, is_mask);
1108 SW_FLOW_KEY_PUT(match, ct.orig_tp.src, ct->src_port, is_mask); 1108 SW_FLOW_KEY_PUT(match, ct.orig_tp.src, ct->src_port, is_mask);
1109 SW_FLOW_KEY_PUT(match, ct.orig_tp.dst, ct->dst_port, is_mask); 1109 SW_FLOW_KEY_PUT(match, ct.orig_tp.dst, ct->dst_port, is_mask);
1110 SW_FLOW_KEY_PUT(match, ct.orig_proto, ct->ipv4_proto, is_mask); 1110 SW_FLOW_KEY_PUT(match, ct_orig_proto, ct->ipv4_proto, is_mask);
1111 *attrs &= ~(1ULL << OVS_KEY_ATTR_CT_ORIG_TUPLE_IPV4); 1111 *attrs &= ~(1ULL << OVS_KEY_ATTR_CT_ORIG_TUPLE_IPV4);
1112 } 1112 }
1113 if (*attrs & (1ULL << OVS_KEY_ATTR_CT_ORIG_TUPLE_IPV6)) { 1113 if (*attrs & (1ULL << OVS_KEY_ATTR_CT_ORIG_TUPLE_IPV6)) {
@@ -1123,7 +1123,7 @@ static int metadata_from_nlattrs(struct net *net, struct sw_flow_match *match,
1123 is_mask); 1123 is_mask);
1124 SW_FLOW_KEY_PUT(match, ct.orig_tp.src, ct->src_port, is_mask); 1124 SW_FLOW_KEY_PUT(match, ct.orig_tp.src, ct->src_port, is_mask);
1125 SW_FLOW_KEY_PUT(match, ct.orig_tp.dst, ct->dst_port, is_mask); 1125 SW_FLOW_KEY_PUT(match, ct.orig_tp.dst, ct->dst_port, is_mask);
1126 SW_FLOW_KEY_PUT(match, ct.orig_proto, ct->ipv6_proto, is_mask); 1126 SW_FLOW_KEY_PUT(match, ct_orig_proto, ct->ipv6_proto, is_mask);
1127 *attrs &= ~(1ULL << OVS_KEY_ATTR_CT_ORIG_TUPLE_IPV6); 1127 *attrs &= ~(1ULL << OVS_KEY_ATTR_CT_ORIG_TUPLE_IPV6);
1128 } 1128 }
1129 1129
@@ -1564,6 +1564,9 @@ int ovs_nla_get_flow_metadata(struct net *net,
1564 memset(&match, 0, sizeof(match)); 1564 memset(&match, 0, sizeof(match));
1565 match.key = key; 1565 match.key = key;
1566 1566
1567 key->ct_state = 0;
1568 key->ct_zone = 0;
1569 key->ct_orig_proto = 0;
1567 memset(&key->ct, 0, sizeof(key->ct)); 1570 memset(&key->ct, 0, sizeof(key->ct));
1568 memset(&key->ipv4.ct_orig, 0, sizeof(key->ipv4.ct_orig)); 1571 memset(&key->ipv4.ct_orig, 0, sizeof(key->ipv4.ct_orig));
1569 memset(&key->ipv6.ct_orig, 0, sizeof(key->ipv6.ct_orig)); 1572 memset(&key->ipv6.ct_orig, 0, sizeof(key->ipv6.ct_orig));