diff options
Diffstat (limited to 'net')
| -rw-r--r-- | net/openvswitch/conntrack.c | 40 | ||||
| -rw-r--r-- | net/openvswitch/conntrack.h | 8 | ||||
| -rw-r--r-- | net/openvswitch/flow.h | 14 | ||||
| -rw-r--r-- | net/openvswitch/flow_netlink.c | 11 |
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) | |||
| 259 | int ovs_ct_put_key(const struct sw_flow_key *swkey, | 259 | int 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, | |||
| 76 | static inline void ovs_ct_fill_key(const struct sk_buff *skb, | 76 | static 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 | ||
| 89 | static inline int ovs_ct_put_key(const struct sw_flow_key *swkey, | 89 | static 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)); |
