void ovs_flow_stats_update(struct sw_flow *flow, struct sk_buff *skb)
 {
        struct flow_stats *stats;
-       __be16 tcp_flags = 0;
+       __be16 tcp_flags = flow->key.tp.flags;
        int node = numa_node_id();
 
        stats = rcu_dereference(flow->stats[node]);
 
-       if (likely(flow->key.ip.proto == IPPROTO_TCP)) {
-               if (likely(flow->key.eth.type == htons(ETH_P_IP)))
-                       tcp_flags = flow->key.ipv4.tp.flags;
-               else if (likely(flow->key.eth.type == htons(ETH_P_IPV6)))
-                       tcp_flags = flow->key.ipv6.tp.flags;
-       }
        /* Check if already have node-specific stats. */
        if (likely(stats)) {
                spin_lock(&stats->lock);
        /* The ICMPv6 type and code fields use the 16-bit transport port
         * fields, so we need to store them in 16-bit network byte order.
         */
-       key->ipv6.tp.src = htons(icmp->icmp6_type);
-       key->ipv6.tp.dst = htons(icmp->icmp6_code);
+       key->tp.src = htons(icmp->icmp6_type);
+       key->tp.dst = htons(icmp->icmp6_code);
 
        if (icmp->icmp6_code == 0 &&
            (icmp->icmp6_type == NDISC_NEIGHBOUR_SOLICITATION ||
                if (key->ip.proto == IPPROTO_TCP) {
                        if (tcphdr_ok(skb)) {
                                struct tcphdr *tcp = tcp_hdr(skb);
-                               key->ipv4.tp.src = tcp->source;
-                               key->ipv4.tp.dst = tcp->dest;
-                               key->ipv4.tp.flags = TCP_FLAGS_BE16(tcp);
+                               key->tp.src = tcp->source;
+                               key->tp.dst = tcp->dest;
+                               key->tp.flags = TCP_FLAGS_BE16(tcp);
                        }
                } else if (key->ip.proto == IPPROTO_UDP) {
                        if (udphdr_ok(skb)) {
                                struct udphdr *udp = udp_hdr(skb);
-                               key->ipv4.tp.src = udp->source;
-                               key->ipv4.tp.dst = udp->dest;
+                               key->tp.src = udp->source;
+                               key->tp.dst = udp->dest;
                        }
                } else if (key->ip.proto == IPPROTO_SCTP) {
                        if (sctphdr_ok(skb)) {
                                struct sctphdr *sctp = sctp_hdr(skb);
-                               key->ipv4.tp.src = sctp->source;
-                               key->ipv4.tp.dst = sctp->dest;
+                               key->tp.src = sctp->source;
+                               key->tp.dst = sctp->dest;
                        }
                } else if (key->ip.proto == IPPROTO_ICMP) {
                        if (icmphdr_ok(skb)) {
                                /* The ICMP type and code fields use the 16-bit
                                 * transport port fields, so we need to store
                                 * them in 16-bit network byte order. */
-                               key->ipv4.tp.src = htons(icmp->type);
-                               key->ipv4.tp.dst = htons(icmp->code);
+                               key->tp.src = htons(icmp->type);
+                               key->tp.dst = htons(icmp->code);
                        }
                }
 
                if (key->ip.proto == NEXTHDR_TCP) {
                        if (tcphdr_ok(skb)) {
                                struct tcphdr *tcp = tcp_hdr(skb);
-                               key->ipv6.tp.src = tcp->source;
-                               key->ipv6.tp.dst = tcp->dest;
-                               key->ipv6.tp.flags = TCP_FLAGS_BE16(tcp);
+                               key->tp.src = tcp->source;
+                               key->tp.dst = tcp->dest;
+                               key->tp.flags = TCP_FLAGS_BE16(tcp);
                        }
                } else if (key->ip.proto == NEXTHDR_UDP) {
                        if (udphdr_ok(skb)) {
                                struct udphdr *udp = udp_hdr(skb);
-                               key->ipv6.tp.src = udp->source;
-                               key->ipv6.tp.dst = udp->dest;
+                               key->tp.src = udp->source;
+                               key->tp.dst = udp->dest;
                        }
                } else if (key->ip.proto == NEXTHDR_SCTP) {
                        if (sctphdr_ok(skb)) {
                                struct sctphdr *sctp = sctp_hdr(skb);
-                               key->ipv6.tp.src = sctp->source;
-                               key->ipv6.tp.dst = sctp->dest;
+                               key->tp.src = sctp->source;
+                               key->tp.dst = sctp->dest;
                        }
                } else if (key->ip.proto == NEXTHDR_ICMP) {
                        if (icmp6hdr_ok(skb)) {
 
                                if (match->mask && (match->mask->key.ip.proto == 0xff))
                                        mask_allowed |= 1 << OVS_KEY_ATTR_ICMPV6;
 
-                               if (match->key->ipv6.tp.src ==
+                               if (match->key->tp.src ==
                                                htons(NDISC_NEIGHBOUR_SOLICITATION) ||
-                                   match->key->ipv6.tp.src == htons(NDISC_NEIGHBOUR_ADVERTISEMENT)) {
+                                   match->key->tp.src == htons(NDISC_NEIGHBOUR_ADVERTISEMENT)) {
                                        key_expected |= 1 << OVS_KEY_ATTR_ND;
-                                       if (match->mask && (match->mask->key.ipv6.tp.src == htons(0xffff)))
+                                       if (match->mask && (match->mask->key.tp.src == htons(0xffff)))
                                                mask_allowed |= 1 << OVS_KEY_ATTR_ND;
                                }
                        }
                const struct ovs_key_tcp *tcp_key;
 
                tcp_key = nla_data(a[OVS_KEY_ATTR_TCP]);
-               if (orig_attrs & (1 << OVS_KEY_ATTR_IPV4)) {
-                       SW_FLOW_KEY_PUT(match, ipv4.tp.src,
-                                       tcp_key->tcp_src, is_mask);
-                       SW_FLOW_KEY_PUT(match, ipv4.tp.dst,
-                                       tcp_key->tcp_dst, is_mask);
-               } else {
-                       SW_FLOW_KEY_PUT(match, ipv6.tp.src,
-                                       tcp_key->tcp_src, is_mask);
-                       SW_FLOW_KEY_PUT(match, ipv6.tp.dst,
-                                       tcp_key->tcp_dst, is_mask);
-               }
+               SW_FLOW_KEY_PUT(match, tp.src, tcp_key->tcp_src, is_mask);
+               SW_FLOW_KEY_PUT(match, tp.dst, tcp_key->tcp_dst, is_mask);
                attrs &= ~(1 << OVS_KEY_ATTR_TCP);
        }
 
        if (attrs & (1 << OVS_KEY_ATTR_TCP_FLAGS)) {
                if (orig_attrs & (1 << OVS_KEY_ATTR_IPV4)) {
-                       SW_FLOW_KEY_PUT(match, ipv4.tp.flags,
+                       SW_FLOW_KEY_PUT(match, tp.flags,
                                        nla_get_be16(a[OVS_KEY_ATTR_TCP_FLAGS]),
                                        is_mask);
                } else {
-                       SW_FLOW_KEY_PUT(match, ipv6.tp.flags,
+                       SW_FLOW_KEY_PUT(match, tp.flags,
                                        nla_get_be16(a[OVS_KEY_ATTR_TCP_FLAGS]),
                                        is_mask);
                }
                const struct ovs_key_udp *udp_key;
 
                udp_key = nla_data(a[OVS_KEY_ATTR_UDP]);
-               if (orig_attrs & (1 << OVS_KEY_ATTR_IPV4)) {
-                       SW_FLOW_KEY_PUT(match, ipv4.tp.src,
-                                       udp_key->udp_src, is_mask);
-                       SW_FLOW_KEY_PUT(match, ipv4.tp.dst,
-                                       udp_key->udp_dst, is_mask);
-               } else {
-                       SW_FLOW_KEY_PUT(match, ipv6.tp.src,
-                                       udp_key->udp_src, is_mask);
-                       SW_FLOW_KEY_PUT(match, ipv6.tp.dst,
-                                       udp_key->udp_dst, is_mask);
-               }
+               SW_FLOW_KEY_PUT(match, tp.src, udp_key->udp_src, is_mask);
+               SW_FLOW_KEY_PUT(match, tp.dst, udp_key->udp_dst, is_mask);
                attrs &= ~(1 << OVS_KEY_ATTR_UDP);
        }
 
                const struct ovs_key_sctp *sctp_key;
 
                sctp_key = nla_data(a[OVS_KEY_ATTR_SCTP]);
-               if (orig_attrs & (1 << OVS_KEY_ATTR_IPV4)) {
-                       SW_FLOW_KEY_PUT(match, ipv4.tp.src,
-                                       sctp_key->sctp_src, is_mask);
-                       SW_FLOW_KEY_PUT(match, ipv4.tp.dst,
-                                       sctp_key->sctp_dst, is_mask);
-               } else {
-                       SW_FLOW_KEY_PUT(match, ipv6.tp.src,
-                                       sctp_key->sctp_src, is_mask);
-                       SW_FLOW_KEY_PUT(match, ipv6.tp.dst,
-                                       sctp_key->sctp_dst, is_mask);
-               }
+               SW_FLOW_KEY_PUT(match, tp.src, sctp_key->sctp_src, is_mask);
+               SW_FLOW_KEY_PUT(match, tp.dst, sctp_key->sctp_dst, is_mask);
                attrs &= ~(1 << OVS_KEY_ATTR_SCTP);
        }
 
                const struct ovs_key_icmp *icmp_key;
 
                icmp_key = nla_data(a[OVS_KEY_ATTR_ICMP]);
-               SW_FLOW_KEY_PUT(match, ipv4.tp.src,
+               SW_FLOW_KEY_PUT(match, tp.src,
                                htons(icmp_key->icmp_type), is_mask);
-               SW_FLOW_KEY_PUT(match, ipv4.tp.dst,
+               SW_FLOW_KEY_PUT(match, tp.dst,
                                htons(icmp_key->icmp_code), is_mask);
                attrs &= ~(1 << OVS_KEY_ATTR_ICMP);
        }
                const struct ovs_key_icmpv6 *icmpv6_key;
 
                icmpv6_key = nla_data(a[OVS_KEY_ATTR_ICMPV6]);
-               SW_FLOW_KEY_PUT(match, ipv6.tp.src,
+               SW_FLOW_KEY_PUT(match, tp.src,
                                htons(icmpv6_key->icmpv6_type), is_mask);
-               SW_FLOW_KEY_PUT(match, ipv6.tp.dst,
+               SW_FLOW_KEY_PUT(match, tp.dst,
                                htons(icmpv6_key->icmpv6_code), is_mask);
                attrs &= ~(1 << OVS_KEY_ATTR_ICMPV6);
        }
                        if (!nla)
                                goto nla_put_failure;
                        tcp_key = nla_data(nla);
-                       if (swkey->eth.type == htons(ETH_P_IP)) {
-                               tcp_key->tcp_src = output->ipv4.tp.src;
-                               tcp_key->tcp_dst = output->ipv4.tp.dst;
-                               if (nla_put_be16(skb, OVS_KEY_ATTR_TCP_FLAGS,
-                                                output->ipv4.tp.flags))
-                                       goto nla_put_failure;
-                       } else if (swkey->eth.type == htons(ETH_P_IPV6)) {
-                               tcp_key->tcp_src = output->ipv6.tp.src;
-                               tcp_key->tcp_dst = output->ipv6.tp.dst;
-                               if (nla_put_be16(skb, OVS_KEY_ATTR_TCP_FLAGS,
-                                                output->ipv6.tp.flags))
-                                       goto nla_put_failure;
-                       }
+                       tcp_key->tcp_src = output->tp.src;
+                       tcp_key->tcp_dst = output->tp.dst;
+                       if (nla_put_be16(skb, OVS_KEY_ATTR_TCP_FLAGS,
+                                        output->tp.flags))
+                               goto nla_put_failure;
                } else if (swkey->ip.proto == IPPROTO_UDP) {
                        struct ovs_key_udp *udp_key;
 
                        if (!nla)
                                goto nla_put_failure;
                        udp_key = nla_data(nla);
-                       if (swkey->eth.type == htons(ETH_P_IP)) {
-                               udp_key->udp_src = output->ipv4.tp.src;
-                               udp_key->udp_dst = output->ipv4.tp.dst;
-                       } else if (swkey->eth.type == htons(ETH_P_IPV6)) {
-                               udp_key->udp_src = output->ipv6.tp.src;
-                               udp_key->udp_dst = output->ipv6.tp.dst;
-                       }
+                       udp_key->udp_src = output->tp.src;
+                       udp_key->udp_dst = output->tp.dst;
                } else if (swkey->ip.proto == IPPROTO_SCTP) {
                        struct ovs_key_sctp *sctp_key;
 
                        if (!nla)
                                goto nla_put_failure;
                        sctp_key = nla_data(nla);
-                       if (swkey->eth.type == htons(ETH_P_IP)) {
-                               sctp_key->sctp_src = output->ipv4.tp.src;
-                               sctp_key->sctp_dst = output->ipv4.tp.dst;
-                       } else if (swkey->eth.type == htons(ETH_P_IPV6)) {
-                               sctp_key->sctp_src = output->ipv6.tp.src;
-                               sctp_key->sctp_dst = output->ipv6.tp.dst;
-                       }
+                       sctp_key->sctp_src = output->tp.src;
+                       sctp_key->sctp_dst = output->tp.dst;
                } else if (swkey->eth.type == htons(ETH_P_IP) &&
                           swkey->ip.proto == IPPROTO_ICMP) {
                        struct ovs_key_icmp *icmp_key;
                        if (!nla)
                                goto nla_put_failure;
                        icmp_key = nla_data(nla);
-                       icmp_key->icmp_type = ntohs(output->ipv4.tp.src);
-                       icmp_key->icmp_code = ntohs(output->ipv4.tp.dst);
+                       icmp_key->icmp_type = ntohs(output->tp.src);
+                       icmp_key->icmp_code = ntohs(output->tp.dst);
                } else if (swkey->eth.type == htons(ETH_P_IPV6) &&
                           swkey->ip.proto == IPPROTO_ICMPV6) {
                        struct ovs_key_icmpv6 *icmpv6_key;
                        if (!nla)
                                goto nla_put_failure;
                        icmpv6_key = nla_data(nla);
-                       icmpv6_key->icmpv6_type = ntohs(output->ipv6.tp.src);
-                       icmpv6_key->icmpv6_code = ntohs(output->ipv6.tp.dst);
+                       icmpv6_key->icmpv6_type = ntohs(output->tp.src);
+                       icmpv6_key->icmpv6_code = ntohs(output->tp.dst);
 
                        if (icmpv6_key->icmpv6_type == NDISC_NEIGHBOUR_SOLICITATION ||
                            icmpv6_key->icmpv6_type == NDISC_NEIGHBOUR_ADVERTISEMENT) {
 
 static int validate_tp_port(const struct sw_flow_key *flow_key)
 {
-       if (flow_key->eth.type == htons(ETH_P_IP)) {
-               if (flow_key->ipv4.tp.src || flow_key->ipv4.tp.dst)
-                       return 0;
-       } else if (flow_key->eth.type == htons(ETH_P_IPV6)) {
-               if (flow_key->ipv6.tp.src || flow_key->ipv6.tp.dst)
-                       return 0;
-       }
+       if ((flow_key->eth.type == htons(ETH_P_IP) ||
+            flow_key->eth.type == htons(ETH_P_IPV6)) &&
+           (flow_key->tp.src || flow_key->tp.dst))
+               return 0;
 
        return -EINVAL;
 }