+void
+ipv6_compose(struct dp_packet *packet, uint8_t proto,
+ const struct in6_addr *src, const struct in6_addr *dst,
+ uint8_t key_tc, ovs_be32 key_fl, uint8_t key_hl)
+{
+ struct ovs_16aligned_ip6_hdr *ip6 = dp_packet_l3(packet);
+ ovs_be32 old_flow;
+ ip6->ip6_vfc = 0x60;
+ ip6->ip6_nxt = proto;
+ ip6->ip6_hlim = key_hl;
+ ip6->ip6_plen = 0;
+ old_flow = get_16aligned_be32(&ip6->ip6_flow) & htonl(0xF00FFFFF | ~IPV6_LABEL_MASK);
+ put_16aligned_be32(&ip6->ip6_flow, old_flow | key_fl | htonl(key_tc << 20));
+ memcpy(&ip6->ip6_src, src, sizeof(ovs_be32[4]));
+ memcpy(&ip6->ip6_dst, dst, sizeof(ovs_be32[4]));
+ dp_packet_set_l4(packet, ip6 + 1);
+}
+