/*
 * QEMU rocker switch emulation - OF-DPA flow processing support
 *
 * Copyright (c) 2014 Scott Feldman <sfeldma@gmail.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 */

#include "qemu/osdep.h"
#include "net/eth.h"
#include "qemu/iov.h"
#include "qemu/timer.h"
#include "qmp-commands.h"

#include "rocker.h"
#include "rocker_hw.h"
#include "rocker_fp.h"
#include "rocker_tlv.h"
#include "rocker_world.h"
#include "rocker_desc.h"
#include "rocker_of_dpa.h"

static const MACAddr zero_mac = { .a = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } };
static const MACAddr ff_mac =   { .a = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff } };

typedef struct of_dpa {
    World *world;
    GHashTable *flow_tbl;
    GHashTable *group_tbl;
    unsigned int flow_tbl_max_size;
    unsigned int group_tbl_max_size;
} OfDpa;

/* flow_key stolen mostly from OVS
 *
 * Note: fields that compare with network packet header fields
 * are stored in network order (BE) to avoid per-packet field
 * byte-swaps.
 */

typedef struct of_dpa_flow_key {
    uint32_t in_pport;               /* ingress port */
    uint32_t tunnel_id;              /* overlay tunnel id */
    uint32_t tbl_id;                 /* table id */
    struct {
        __be16 vlan_id;              /* 0 if no VLAN */
        MACAddr src;                 /* ethernet source address */
        MACAddr dst;                 /* ethernet destination address */
        __be16 type;                 /* ethernet frame type */
    } eth;
    struct {
        uint8_t proto;               /* IP protocol or ARP opcode */
        uint8_t tos;                 /* IP ToS */
        uint8_t ttl;                 /* IP TTL/hop limit */
        uint8_t frag;                /* one of FRAG_TYPE_* */
    } ip;
    union {
        struct {
            struct {
                __be32 src;          /* IP source address */
                __be32 dst;          /* IP destination address */
            } addr;
            union {
                struct {
                    __be16 src;      /* TCP/UDP/SCTP source port */
                    __be16 dst;      /* TCP/UDP/SCTP destination port */
                    __be16 flags;    /* TCP flags */
                } tp;
                struct {
                    MACAddr sha;     /* ARP source hardware address */
                    MACAddr tha;     /* ARP target hardware address */
                } arp;
            };
        } ipv4;
        struct {
            struct {
                Ipv6Addr src;       /* IPv6 source address */
                Ipv6Addr dst;       /* IPv6 destination address */
            } addr;
            __be32 label;            /* IPv6 flow label */
            struct {
                __be16 src;          /* TCP/UDP/SCTP source port */
                __be16 dst;          /* TCP/UDP/SCTP destination port */
                __be16 flags;        /* TCP flags */
            } tp;
            struct {
                Ipv6Addr target;    /* ND target address */
                MACAddr sll;         /* ND source link layer address */
                MACAddr tll;         /* ND target link layer address */
            } nd;
        } ipv6;
    };
    int width;                       /* how many uint64_t's in key? */
} OfDpaFlowKey;

/* Width of key which includes field 'f' in u64s, rounded up */
#define FLOW_KEY_WIDTH(f) \
    DIV_ROUND_UP(offsetof(OfDpaFlowKey, f) + sizeof(((OfDpaFlowKey *)0)->f), \
    sizeof(uint64_t))

typedef struct of_dpa_flow_action {
    uint32_t goto_tbl;
    struct {
        uint32_t group_id;
        uint32_t tun_log_lport;
        __be16 vlan_id;
    } write;
    struct {
        __be16 new_vlan_id;
        uint32_t out_pport;
        uint8_t copy_to_cpu;
        __be16 vlan_id;
    } apply;
} OfDpaFlowAction;

typedef struct of_dpa_flow {
    uint32_t lpm;
    uint32_t priority;
    uint32_t hardtime;
    uint32_t idletime;
    uint64_t cookie;
    OfDpaFlowKey key;
    OfDpaFlowKey mask;
    OfDpaFlowAction action;
    struct {
        uint64_t hits;
        int64_t install_time;
        int64_t refresh_time;
        uint64_t rx_pkts;
        uint64_t tx_pkts;
    } stats;
} OfDpaFlow;

typedef struct of_dpa_flow_pkt_fields {
    uint32_t tunnel_id;
    struct eth_header *ethhdr;
    __be16 *h_proto;
    struct vlan_header *vlanhdr;
    struct ip_header *ipv4hdr;
    struct ip6_header *ipv6hdr;
    Ipv6Addr *ipv6_src_addr;
    Ipv6Addr *ipv6_dst_addr;
} OfDpaFlowPktFields;

typedef struct of_dpa_flow_context {
    uint32_t in_pport;
    uint32_t tunnel_id;
    struct iovec *iov;
    int iovcnt;
    struct eth_header ethhdr_rewrite;
    struct vlan_header vlanhdr_rewrite;
    struct vlan_header vlanhdr;
    OfDpa *of_dpa;
    OfDpaFlowPktFields fields;
    OfDpaFlowAction action_set;
} OfDpaFlowContext;

typedef struct of_dpa_flow_match {
    OfDpaFlowKey value;
    OfDpaFlow *best;
} OfDpaFlowMatch;

typedef struct of_dpa_group {
    uint32_t id;
    union {
        struct {
            uint32_t out_pport;
            uint8_t pop_vlan;
        } l2_interface;
        struct {
            uint32_t group_id;
            MACAddr src_mac;
            MACAddr dst_mac;
            __be16 vlan_id;
        } l2_rewrite;
        struct {
            uint16_t group_count;
            uint32_t *group_ids;
        } l2_flood;
        struct {
            uint32_t group_id;
            MACAddr src_mac;
            MACAddr dst_mac;
            __be16 vlan_id;
            uint8_t ttl_check;
        } l3_unicast;
    };
} OfDpaGroup;

static int of_dpa_mask2prefix(__be32 mask)
{
    int i;
    int count = 32;

    for (i = 0; i < 32; i++) {
        if (!(ntohl(mask) & ((2 << i) - 1))) {
            count--;
        }
    }

    return count;
}

#if defined(DEBUG_ROCKER)
static void of_dpa_flow_key_dump(OfDpaFlowKey *key, OfDpaFlowKey *mask)
{
    char buf[512], *b = buf, *mac;

    b += sprintf(b, " tbl %2d", key->tbl_id);

    if (key->in_pport || (mask && mask->in_pport)) {
        b += sprintf(b, " in_pport %2d", key->in_pport);
        if (mask && mask->in_pport != 0xffffffff) {
            b += sprintf(b, "/0x%08x", key->in_pport);
        }
    }

    if (key->tunnel_id || (mask && mask->tunnel_id)) {
        b += sprintf(b, " tun %8d", key->tunnel_id);
        if (mask && mask->tunnel_id != 0xffffffff) {
            b += sprintf(b, "/0x%08x", key->tunnel_id);
        }
    }

    if (key->eth.vlan_id || (mask && mask->eth.vlan_id)) {
        b += sprintf(b, " vlan %4d", ntohs(key->eth.vlan_id));
        if (mask && mask->eth.vlan_id != 0xffff) {
            b += sprintf(b, "/0x%04x", ntohs(key->eth.vlan_id));
        }
    }

    if (memcmp(key->eth.src.a, zero_mac.a, ETH_ALEN) ||
        (mask && memcmp(mask->eth.src.a, zero_mac.a, ETH_ALEN))) {
        mac = qemu_mac_strdup_printf(key->eth.src.a);
        b += sprintf(b, " src %s", mac);
        g_free(mac);
        if (mask && memcmp(mask->eth.src.a, ff_mac.a, ETH_ALEN)) {
            mac = qemu_mac_strdup_printf(mask->eth.src.a);
            b += sprintf(b, "/%s", mac);
            g_free(mac);
        }
    }

    if (memcmp(key->eth.dst.a, zero_mac.a, ETH_ALEN) ||
        (mask && memcmp(mask->eth.dst.a, zero_mac.a, ETH_ALEN))) {
        mac = qemu_mac_strdup_printf(key->eth.dst.a);
        b += sprintf(b, " dst %s", mac);
        g_free(mac);
        if (mask && memcmp(mask->eth.dst.a, ff_mac.a, ETH_ALEN)) {
            mac = qemu_mac_strdup_printf(mask->eth.dst.a);
            b += sprintf(b, "/%s", mac);
            g_free(mac);
        }
    }

    if (key->eth.type || (mask && mask->eth.type)) {
        b += sprintf(b, " type 0x%04x", ntohs(key->eth.type));
        if (mask && mask->eth.type != 0xffff) {
            b += sprintf(b, "/0x%04x", ntohs(mask->eth.type));
        }
        switch (ntohs(key->eth.type)) {
        case 0x0800:
        case 0x86dd:
            if (key->ip.proto || (mask && mask->ip.proto)) {
                b += sprintf(b, " ip proto %2d", key->ip.proto);
                if (mask && mask->ip.proto != 0xff) {
                    b += sprintf(b, "/0x%02x", mask->ip.proto);
                }
            }
            if (key->ip.tos || (mask && mask->ip.tos)) {
                b += sprintf(b, " ip tos %2d", key->ip.tos);
                if (mask && mask->ip.tos != 0xff) {
                    b += sprintf(b, "/0x%02x", mask->ip.tos);
                }
            }
            break;
        }
        switch (ntohs(key->eth.type)) {
        case 0x0800:
            if (key->ipv4.addr.dst || (mask && mask->ipv4.addr.dst)) {
                b += sprintf(b, " dst %s",
                    inet_ntoa(*(struct in_addr *)&key->ipv4.addr.dst));
                if (mask) {
                    b += sprintf(b, "/%d",
                                 of_dpa_mask2prefix(mask->ipv4.addr.dst));
                }
            }
            break;
        }
    }

    DPRINTF("%s\n", buf);
}
#else
#define of_dpa_flow_key_dump(k, m)
#endif

static void _of_dpa_flow_match(void *key, void *value, void *user_data)
{
    OfDpaFlow *flow = value;
    OfDpaFlowMatch *match = user_data;
    uint64_t *k = (uint64_t *)&flow->key;
    uint64_t *m = (uint64_t *)&flow->mask;
    uint64_t *v = (uint64_t *)&match->value;
    int i;

    if (flow->key.tbl_id == match->value.tbl_id) {
        of_dpa_flow_key_dump(&flow->key, &flow->mask);
    }

    if (flow->key.width > match->value.width) {
        return;
    }

    for (i = 0; i < flow->key.width; i++, k++, m++, v++) {
        if ((~*k & *m & *v) | (*k & *m & ~*v)) {
            return;
        }
    }

    DPRINTF("match\n");

    if (!match->best ||
        flow->priority > match->best->priority ||
        flow->lpm > match->best->lpm) {
        match->best = flow;
    }
}

static OfDpaFlow *of_dpa_flow_match(OfDpa *of_dpa, OfDpaFlowMatch *match)
{
    DPRINTF("\nnew search\n");
    of_dpa_flow_key_dump(&match->value, NULL);

    g_hash_table_foreach(of_dpa->flow_tbl, _of_dpa_flow_match, match);

    return match->best;
}

static OfDpaFlow *of_dpa_flow_find(OfDpa *of_dpa, uint64_t cookie)
{
    return g_hash_table_lookup(of_dpa->flow_tbl, &cookie);
}

static int of_dpa_flow_add(OfDpa *of_dpa, OfDpaFlow *flow)
{
    g_hash_table_insert(of_dpa->flow_tbl, &flow->cookie, flow);

    return ROCKER_OK;
}

static void of_dpa_flow_del(OfDpa *of_dpa, OfDpaFlow *flow)
{
    g_hash_table_remove(of_dpa->flow_tbl, &flow->cookie);
}

static OfDpaFlow *of_dpa_flow_alloc(uint64_t cookie)
{
    OfDpaFlow *flow;
    int64_t now = qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) / 1000;

    flow = g_new0(OfDpaFlow, 1);
    if (!flow) {
        return NULL;
    }

    flow->cookie = cookie;
    flow->mask.tbl_id = 0xffffffff;

    flow->stats.install_time = flow->stats.refresh_time = now;

    return flow;
}

static void of_dpa_flow_pkt_hdr_reset(OfDpaFlowContext *fc)
{
    OfDpaFlowPktFields *fields = &fc->fields;

    fc->iov[0].iov_base = fields->ethhdr;
    fc->iov[0].iov_len = sizeof(struct eth_header);
    fc->iov[1].iov_base = fields->vlanhdr;
    fc->iov[1].iov_len = fields->vlanhdr ? sizeof(struct vlan_header) : 0;
}

static void of_dpa_flow_pkt_parse(OfDpaFlowContext *fc,
                                  const struct iovec *iov, int iovcnt)
{
    OfDpaFlowPktFields *fields = &fc->fields;
    size_t sofar = 0;
    int i;

    sofar += sizeof(struct eth_header);
    if (iov->iov_len < sofar) {
        DPRINTF("flow_pkt_parse underrun on eth_header\n");
        return;
    }

    fields->ethhdr = iov->iov_base;
    fields->h_proto = &fields->ethhdr->h_proto;

    if (ntohs(*fields->h_proto) == ETH_P_VLAN) {
        sofar += sizeof(struct vlan_header);
        if (iov->iov_len < sofar) {
            DPRINTF("flow_pkt_parse underrun on vlan_header\n");
            return;
        }
        fields->vlanhdr = (struct vlan_header *)(fields->ethhdr + 1);
        fields->h_proto = &fields->vlanhdr->h_proto;
    }

    switch (ntohs(*fields->h_proto)) {
    case ETH_P_IP:
        sofar += sizeof(struct ip_header);
        if (iov->iov_len < sofar) {
            DPRINTF("flow_pkt_parse underrun on ip_header\n");
            return;
        }
        fields->ipv4hdr = (struct ip_header *)(fields->h_proto + 1);
        break;
    case ETH_P_IPV6:
        sofar += sizeof(struct ip6_header);
        if (iov->iov_len < sofar) {
            DPRINTF("flow_pkt_parse underrun on ip6_header\n");
            return;
        }
        fields->ipv6hdr = (struct ip6_header *)(fields->h_proto + 1);
        break;
    }

    /* To facilitate (potential) VLAN tag insertion, Make a
     * copy of the iov and insert two new vectors at the
     * beginning for eth hdr and vlan hdr.  No data is copied,
     * just the vectors.
     */

    of_dpa_flow_pkt_hdr_reset(fc);

    fc->iov[2].iov_base = fields->h_proto + 1;
    fc->iov[2].iov_len = iov->iov_len - fc->iov[0].iov_len - fc->iov[1].iov_len;

    for (i = 1; i < iovcnt; i++) {
        fc->iov[i+2] = iov[i];
    }

    fc->iovcnt = iovcnt + 2;
}

static void of_dpa_flow_pkt_insert_vlan(OfDpaFlowContext *fc, __be16 vlan_id)
{
    OfDpaFlowPktFields *fields = &fc->fields;
    uint16_t h_proto = fields->ethhdr->h_proto;

    if (fields->vlanhdr) {
        DPRINTF("flow_pkt_insert_vlan packet already has vlan\n");
        return;
    }

    fields->ethhdr->h_proto = htons(ETH_P_VLAN);
    fields->vlanhdr = &fc->vlanhdr;
    fields->vlanhdr->h_tci = vlan_id;
    fields->vlanhdr->h_proto = h_proto;
    fields->h_proto = &fields->vlanhdr->h_proto;

    fc->iov[1].iov_base = fields->vlanhdr;
    fc->iov[1].iov_len = sizeof(struct vlan_header);
}

static void of_dpa_flow_pkt_strip_vlan(OfDpaFlowContext *fc)
{
    OfDpaFlowPktFields *fields = &fc->fields;

    if (!fields->vlanhdr) {
        return;
    }

    fc->iov[0].iov_len -= sizeof(fields->ethhdr->h_proto);
    fc->iov[1].iov_base = fields->h_proto;
    fc->iov[1].iov_len = sizeof(fields->ethhdr->h_proto);
}

static void of_dpa_flow_pkt_hdr_rewrite(OfDpaFlowContext *fc,
                                        uint8_t *src_mac, uint8_t *dst_mac,
                                        __be16 vlan_id)
{
    OfDpaFlowPktFields *fields = &fc->fields;

    if (src_mac || dst_mac) {
        memcpy(&fc->ethhdr_rewrite, fields->ethhdr, sizeof(struct eth_header));
        if (src_mac && memcmp(src_mac, zero_mac.a, ETH_ALEN)) {
            memcpy(fc->ethhdr_rewrite.h_source, src_mac, ETH_ALEN);
        }
        if (dst_mac && memcmp(dst_mac, zero_mac.a, ETH_ALEN)) {
            memcpy(fc->ethhdr_rewrite.h_dest, dst_mac, ETH_ALEN);
        }
        fc->iov[0].iov_base = &fc->ethhdr_rewrite;
    }

    if (vlan_id && fields->vlanhdr) {
        fc->vlanhdr_rewrite = fc->vlanhdr;
        fc->vlanhdr_rewrite.h_tci = vlan_id;
        fc->iov[1].iov_base = &fc->vlanhdr_rewrite;
    }
}

static void of_dpa_flow_ig_tbl(OfDpaFlowContext *fc, uint32_t tbl_id);

static void of_dpa_ig_port_build_match(OfDpaFlowContext *fc,
                                       OfDpaFlowMatch *match)
{
    match->value.tbl_id = ROCKER_OF_DPA_TABLE_ID_INGRESS_PORT;
    match->value.in_pport = fc->in_pport;
    match->value.width = FLOW_KEY_WIDTH(tbl_id);
}

static void of_dpa_ig_port_miss(OfDpaFlowContext *fc)
{
    uint32_t port;

    /* The default on miss is for packets from physical ports
     * to go to the VLAN Flow Table. There is no default rule
     * for packets from logical ports, which are dropped on miss.
     */

    if (fp_port_from_pport(fc->in_pport, &port)) {
        of_dpa_flow_ig_tbl(fc, ROCKER_OF_DPA_TABLE_ID_VLAN);
    }
}

static void of_dpa_vlan_build_match(OfDpaFlowContext *fc,
                                    OfDpaFlowMatch *match)
{
    match->value.tbl_id = ROCKER_OF_DPA_TABLE_ID_VLAN;
    match->value.in_pport = fc->in_pport;
    if (fc->fields.vlanhdr) {
        match->value.eth.vlan_id = fc->fields.vlanhdr->h_tci;
    }
    match->value.width = FLOW_KEY_WIDTH(eth.vlan_id);
}

static void of_dpa_vlan_insert(OfDpaFlowContext *fc,
                               OfDpaFlow *flow)
{
    if (flow->action.apply.new_vlan_id) {
        of_dpa_flow_pkt_insert_vlan(fc, flow->action.apply.new_vlan_id);
    }
}

static void of_dpa_term_mac_build_match(OfDpaFlowContext *fc,
                                        OfDpaFlowMatch *match)
{
    match->value.tbl_id = ROCKER_OF_DPA_TABLE_ID_TERMINATION_MAC;
    match->value.in_pport = fc->in_pport;
    match->value.eth.type = *fc->fields.h_proto;
    match->value.eth.vlan_id = fc->fields.vlanhdr->h_tci;
    memcpy(match->value.eth.dst.a, fc->fields.ethhdr->h_dest,
           sizeof(match->value.eth.dst.a));
    match->value.width = FLOW_KEY_WIDTH(eth.type);
}

static void of_dpa_term_mac_miss(OfDpaFlowContext *fc)
{
    of_dpa_flow_ig_tbl(fc, ROCKER_OF_DPA_TABLE_ID_BRIDGING);
}

static void of_dpa_apply_actions(OfDpaFlowContext *fc,
                                 OfDpaFlow *flow)
{
    fc->action_set.apply.copy_to_cpu = flow->action.apply.copy_to_cpu;
    fc->action_set.apply.vlan_id = flow->key.eth.vlan_id;
}

static void of_dpa_bridging_build_match(OfDpaFlowContext *fc,
                                        OfDpaFlowMatch *match)
{
    match->value.tbl_id = ROCKER_OF_DPA_TABLE_ID_BRIDGING;
    if (fc->fields.vlanhdr) {
        match->value.eth.vlan_id = fc->fields.vlanhdr->h_tci;
    } else if (fc->tunnel_id) {
        match->value.tunnel_id = fc->tunnel_id;
    }
    memcpy(match->value.eth.dst.a, fc->fields.ethhdr->h_dest,
           sizeof(match->value.eth.dst.a));
    match->value.width = FLOW_KEY_WIDTH(eth.dst);
}

static void of_dpa_bridging_learn(OfDpaFlowContext *fc,
                                  OfDpaFlow *dst_flow)
{
    OfDpaFlowMatch match = { { 0, }, };
    OfDpaFlow *flow;
    uint8_t *addr;
    uint16_t vlan_id;
    int64_t now = qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) / 1000;
    int64_t refresh_delay = 1;

    /* Do a lookup in bridge table by src_mac/vlan */

    addr = fc->fields.ethhdr->h_source;
    vlan_id = fc->fields.vlanhdr->h_tci;

    match.value.tbl_id = ROCKER_OF_DPA_TABLE_ID_BRIDGING;
    match.value.eth.vlan_id = vlan_id;
    memcpy(match.value.eth.dst.a, addr, sizeof(match.value.eth.dst.a));
    match.value.width = FLOW_KEY_WIDTH(eth.dst);

    flow = of_dpa_flow_match(fc->of_dpa, &match);
    if (flow) {
        if (!memcmp(flow->mask.eth.dst.a, ff_mac.a,
                    sizeof(flow->mask.eth.dst.a))) {
            /* src_mac/vlan already learned; if in_port and out_port
             * don't match, the end station has moved and the port
             * needs updating */
            /* XXX implement the in_port/out_port check */
            if (now - flow->stats.refresh_time < refresh_delay) {
                return;
            }
            flow->stats.refresh_time = now;
        }
    }

    /* Let driver know about mac/vlan.  This may be a new mac/vlan
     * or a refresh of existing mac/vlan that's been hit after the
     * refresh_delay.
     */

    rocker_event_mac_vlan_seen(world_rocker(fc->of_dpa->world),
                               fc->in_pport, addr, vlan_id);
}

static void of_dpa_bridging_miss(OfDpaFlowContext *fc)
{
    of_dpa_bridging_learn(fc, NULL);
    of_dpa_flow_ig_tbl(fc, ROCKER_OF_DPA_TABLE_ID_ACL_POLICY);
}

static void of_dpa_bridging_action_write(OfDpaFlowContext *fc,
                                         OfDpaFlow *flow)
{
    if (flow->action.write.group_id != ROCKER_GROUP_NONE) {
        fc->action_set.write.group_id = flow->action.write.group_id;
    }
    fc->action_set.write.tun_log_lport = flow->action.write.tun_log_lport;
}

static void of_dpa_unicast_routing_build_match(OfDpaFlowContext *fc,
                                               OfDpaFlowMatch *match)
{
    match->value.tbl_id = ROCKER_OF_DPA_TABLE_ID_UNICAST_ROUTING;
    match->value.eth.type = *fc->fields.h_proto;
    if (fc->fields.ipv4hdr) {
        match->value.ipv4.addr.dst = fc->fields.ipv4hdr->ip_dst;
    }
    if (fc->fields.ipv6_dst_addr) {
        memcpy(&match->value.ipv6.addr.dst, fc->fields.ipv6_dst_addr,
               sizeof(match->value.ipv6.addr.dst));
    }
    match->value.width = FLOW_KEY_WIDTH(ipv6.addr.dst);
}

static void of_dpa_unicast_routing_miss(OfDpaFlowContext *fc)
{
    of_dpa_flow_ig_tbl(fc, ROCKER_OF_DPA_TABLE_ID_ACL_POLICY);
}

static void of_dpa_unicast_routing_action_write(OfDpaFlowContext *fc,
                                                OfDpaFlow *flow)
{
    if (flow->action.write.group_id != ROCKER_GROUP_NONE) {
        fc->action_set.write.group_id = flow->action.write.group_id;
    }
}

static void
of_dpa_multicast_routing_build_match(OfDpaFlowContext *fc,
                                     OfDpaFlowMatch *match)
{
    match->value.tbl_id = ROCKER_OF_DPA_TABLE_ID_MULTICAST_ROUTING;
    match->value.eth.type = *fc->fields.h_proto;
    match->value.eth.vlan_id = fc->fields.vlanhdr->h_tci;
    if (fc->fields.ipv4hdr) {
        match->value.ipv4.addr.src = fc->fields.ipv4hdr->ip_src;
        match->value.ipv4.addr.dst = fc->fields.ipv4hdr->ip_dst;
    }
    if (fc->fields.ipv6_src_addr) {
        memcpy(&match->value.ipv6.addr.src, fc->fields.ipv6_src_addr,
               sizeof(match->value.ipv6.addr.src));
    }
    if (fc->fields.ipv6_dst_addr) {
        memcpy(&match->value.ipv6.addr.dst, fc->fields.ipv6_dst_addr,
               sizeof(match->value.ipv6.addr.dst));
    }
    match->value.width = FLOW_KEY_WIDTH(ipv6.addr.dst);
}

static void of_dpa_multicast_routing_miss(OfDpaFlowContext *fc)
{
    of_dpa_flow_ig_tbl(fc, ROCKER_OF_DPA_TABLE_ID_ACL_POLICY);
}

static void
of_dpa_multicast_routing_action_write(OfDpaFlowContext *fc,
                                      OfDpaFlow *flow)
{
    if (flow->action.write.group_id != ROCKER_GROUP_NONE) {
        fc->action_set.write.group_id = flow->action.write.group_id;
    }
    fc->action_set.write.vlan_id = flow->action.write.vlan_id;
}

static void of_dpa_acl_build_match(OfDpaFlowContext *fc,
                                   OfDpaFlowMatch *match)
{
    match->value.tbl_id = ROCKER_OF_DPA_TABLE_ID_ACL_POLICY;
    match->value.in_pport = fc->in_pport;
    memcpy(match->value.eth.src.a, fc->fields.ethhdr->h_source,
           sizeof(match->value.eth.src.a));
    memcpy(match->value.eth.dst.a, fc->fields.ethhdr->h_dest,
           sizeof(match->value.eth.dst.a));
    match->value.eth.type = *fc->fields.h_proto;
    match->value.eth.vlan_id = fc->fields.vlanhdr->h_tci;
    match->value.width = FLOW_KEY_WIDTH(eth.type);
    if (fc->fields.ipv4hdr) {
        match->value.ip.proto = fc->fields.ipv4hdr->ip_p;
        match->value.ip.tos = fc->fields.ipv4hdr->ip_tos;
        match->value.width = FLOW_KEY_WIDTH(ip.tos);
    } else if (fc->fields.ipv6hdr) {
        match->value.ip.proto =
            fc->fields.ipv6hdr->ip6_ctlun.ip6_un1.ip6_un1_nxt;
        match->value.ip.tos = 0; /* XXX what goes here? */
        match->value.width = FLOW_KEY_WIDTH(ip.tos);
    }
}

static void of_dpa_eg(OfDpaFlowContext *fc);
static void of_dpa_acl_hit(OfDpaFlowContext *fc,
                           OfDpaFlow *dst_flow)
{
    of_dpa_eg(fc);
}

static void of_dpa_acl_action_write(OfDpaFlowContext *fc,
                                    OfDpaFlow *flow)
{
    if (flow->action.write.group_id != ROCKER_GROUP_NONE) {
        fc->action_set.write.group_id = flow->action.write.group_id;
    }
}

static void of_dpa_drop(OfDpaFlowContext *fc)
{
    /* drop packet */
}

static OfDpaGroup *of_dpa_group_find(OfDpa *of_dpa,
                                              uint32_t group_id)
{
    return g_hash_table_lookup(of_dpa->group_tbl, &group_id);
}

static int of_dpa_group_add(OfDpa *of_dpa, OfDpaGroup *group)
{
    g_hash_table_insert(of_dpa->group_tbl, &group->id, group);

    return 0;
}

#if 0
static int of_dpa_group_mod(OfDpa *of_dpa, OfDpaGroup *group)
{
    OfDpaGroup *old_group = of_dpa_group_find(of_dpa, group->id);

    if (!old_group) {
        return -ENOENT;
    }

    /* XXX */

    return 0;
}
#endif

static int of_dpa_group_del(OfDpa *of_dpa, OfDpaGroup *group)
{
    g_hash_table_remove(of_dpa->group_tbl, &group->id);

    return 0;
}

#if 0
static int of_dpa_group_get_stats(OfDpa *of_dpa, uint32_t id)
{
    OfDpaGroup *group = of_dpa_group_find(of_dpa, id);

    if (!group) {
        return -ENOENT;
    }

    /* XXX get/return stats */

    return 0;
}
#endif

static OfDpaGroup *of_dpa_group_alloc(uint32_t id)
{
    OfDpaGroup *group = g_new0(OfDpaGroup, 1);

    if (!group) {
        return NULL;
    }

    group->id = id;

    return group;
}

static void of_dpa_output_l2_interface(OfDpaFlowContext *fc,
                                       OfDpaGroup *group)
{
    uint8_t copy_to_cpu = fc->action_set.apply.copy_to_cpu;

    if (group->l2_interface.pop_vlan) {
        of_dpa_flow_pkt_strip_vlan(fc);
    }

    /* Note: By default, and as per the OpenFlow 1.3.1
     * specification, a packet cannot be forwarded back
     * to the IN_PORT from which it came in. An action
     * bucket that specifies the particular packet's
     * egress port is not evaluated.
     */

    if (group->l2_interface.out_pport == 0) {
        rx_produce(fc->of_dpa->world, fc->in_pport, fc->iov, fc->iovcnt,
                   copy_to_cpu);
    } else if (group->l2_interface.out_pport != fc->in_pport) {
        rocker_port_eg(world_rocker(fc->of_dpa->world),
                       group->l2_interface.out_pport,
                       fc->iov, fc->iovcnt);
    }
}

static void of_dpa_output_l2_rewrite(OfDpaFlowContext *fc,
                                     OfDpaGroup *group)
{
    OfDpaGroup *l2_group =
        of_dpa_group_find(fc->of_dpa, group->l2_rewrite.group_id);

    if (!l2_group) {
        return;
    }

    of_dpa_flow_pkt_hdr_rewrite(fc, group->l2_rewrite.src_mac.a,
                         group->l2_rewrite.dst_mac.a,
                         group->l2_rewrite.vlan_id);
    of_dpa_output_l2_interface(fc, l2_group);
}

static void of_dpa_output_l2_flood(OfDpaFlowContext *fc,
                                   OfDpaGroup *group)
{
    OfDpaGroup *l2_group;
    int i;

    for (i = 0; i < group->l2_flood.group_count; i++) {
        of_dpa_flow_pkt_hdr_reset(fc);
        l2_group = of_dpa_group_find(fc->of_dpa, group->l2_flood.group_ids[i]);
        if (!l2_group) {
            continue;
        }
        switch (ROCKER_GROUP_TYPE_GET(l2_group->id)) {
        case ROCKER_OF_DPA_GROUP_TYPE_L2_INTERFACE:
            of_dpa_output_l2_interface(fc, l2_group);
            break;
        case ROCKER_OF_DPA_GROUP_TYPE_L2_REWRITE:
            of_dpa_output_l2_rewrite(fc, l2_group);
            break;
        }
    }
}

static void of_dpa_output_l3_unicast(OfDpaFlowContext *fc, OfDpaGroup *group)
{
    OfDpaGroup *l2_group =
        of_dpa_group_find(fc->of_dpa, group->l3_unicast.group_id);

    if (!l2_group) {
        return;
    }

    of_dpa_flow_pkt_hdr_rewrite(fc, group->l3_unicast.src_mac.a,
                                group->l3_unicast.dst_mac.a,
                                group->l3_unicast.vlan_id);
    /* XXX need ttl_check */
    of_dpa_output_l2_interface(fc, l2_group);
}

static void of_dpa_eg(OfDpaFlowContext *fc)
{
    OfDpaFlowAction *set = &fc->action_set;
    OfDpaGroup *group;
    uint32_t group_id;

    /* send a copy of pkt to CPU (controller)? */

    if (set->apply.copy_to_cpu) {
        group_id = ROCKER_GROUP_L2_INTERFACE(set->apply.vlan_id, 0);
        group = of_dpa_group_find(fc->of_dpa, group_id);
        if (group) {
            of_dpa_output_l2_interface(fc, group);
            of_dpa_flow_pkt_hdr_reset(fc);
        }
    }

    /* process group write actions */

    if (!set->write.group_id) {
        return;
    }

    group = of_dpa_group_find(fc->of_dpa, set->write.group_id);
    if (!group) {
        return;
    }

    switch (ROCKER_GROUP_TYPE_GET(group->id)) {
    case ROCKER_OF_DPA_GROUP_TYPE_L2_INTERFACE:
        of_dpa_output_l2_interface(fc, group);
        break;
    case ROCKER_OF_DPA_GROUP_TYPE_L2_REWRITE:
        of_dpa_output_l2_rewrite(fc, group);
        break;
    case ROCKER_OF_DPA_GROUP_TYPE_L2_FLOOD:
    case ROCKER_OF_DPA_GROUP_TYPE_L2_MCAST:
        of_dpa_output_l2_flood(fc, group);
        break;
    case ROCKER_OF_DPA_GROUP_TYPE_L3_UCAST:
        of_dpa_output_l3_unicast(fc, group);
        break;
    }
}

typedef struct of_dpa_flow_tbl_ops {
    void (*build_match)(OfDpaFlowContext *fc, OfDpaFlowMatch *match);
    void (*hit)(OfDpaFlowContext *fc, OfDpaFlow *flow);
    void (*miss)(OfDpaFlowContext *fc);
    void (*hit_no_goto)(OfDpaFlowContext *fc);
    void (*action_apply)(OfDpaFlowContext *fc, OfDpaFlow *flow);
    void (*action_write)(OfDpaFlowContext *fc, OfDpaFlow *flow);
} OfDpaFlowTblOps;

static OfDpaFlowTblOps of_dpa_tbl_ops[] = {
    [ROCKER_OF_DPA_TABLE_ID_INGRESS_PORT] = {
        .build_match = of_dpa_ig_port_build_match,
        .miss = of_dpa_ig_port_miss,
        .hit_no_goto = of_dpa_drop,
    },
    [ROCKER_OF_DPA_TABLE_ID_VLAN] = {
        .build_match = of_dpa_vlan_build_match,
        .hit_no_goto = of_dpa_drop,
        .action_apply = of_dpa_vlan_insert,
    },
    [ROCKER_OF_DPA_TABLE_ID_TERMINATION_MAC] = {
        .build_match = of_dpa_term_mac_build_match,
        .miss = of_dpa_term_mac_miss,
        .hit_no_goto = of_dpa_drop,
        .action_apply = of_dpa_apply_actions,
    },
    [ROCKER_OF_DPA_TABLE_ID_BRIDGING] = {
        .build_match = of_dpa_bridging_build_match,
        .hit = of_dpa_bridging_learn,
        .miss = of_dpa_bridging_miss,
        .hit_no_goto = of_dpa_drop,
        .action_apply = of_dpa_apply_actions,
        .action_write = of_dpa_bridging_action_write,
    },
    [ROCKER_OF_DPA_TABLE_ID_UNICAST_ROUTING] = {
        .build_match = of_dpa_unicast_routing_build_match,
        .miss = of_dpa_unicast_routing_miss,
        .hit_no_goto = of_dpa_drop,
        .action_write = of_dpa_unicast_routing_action_write,
    },
    [ROCKER_OF_DPA_TABLE_ID_MULTICAST_ROUTING] = {
        .build_match = of_dpa_multicast_routing_build_match,
        .miss = of_dpa_multicast_routing_miss,
        .hit_no_goto = of_dpa_drop,
        .action_write = of_dpa_multicast_routing_action_write,
    },
    [ROCKER_OF_DPA_TABLE_ID_ACL_POLICY] = {
        .build_match = of_dpa_acl_build_match,
        .hit = of_dpa_acl_hit,
        .miss = of_dpa_eg,
        .action_apply = of_dpa_apply_actions,
        .action_write = of_dpa_acl_action_write,
    },
};

static void of_dpa_flow_ig_tbl(OfDpaFlowContext *fc, uint32_t tbl_id)
{
    OfDpaFlowTblOps *ops = &of_dpa_tbl_ops[tbl_id];
    OfDpaFlowMatch match = { { 0, }, };
    OfDpaFlow *flow;

    if (ops->build_match) {
        ops->build_match(fc, &match);
    } else {
        return;
    }

    flow = of_dpa_flow_match(fc->of_dpa, &match);
    if (!flow) {
        if (ops->miss) {
            ops->miss(fc);
        }
        return;
    }

    flow->stats.hits++;

    if (ops->action_apply) {
        ops->action_apply(fc, flow);
    }

    if (ops->action_write) {
        ops->action_write(fc, flow);
    }

    if (ops->hit) {
        ops->hit(fc, flow);
    }

    if (flow->action.goto_tbl) {
        of_dpa_flow_ig_tbl(fc, flow->action.goto_tbl);
    } else if (ops->hit_no_goto) {
        ops->hit_no_goto(fc);
    }

    /* drop packet */
}

static ssize_t of_dpa_ig(World *world, uint32_t pport,
                         const struct iovec *iov, int iovcnt)
{
    struct iovec iov_copy[iovcnt + 2];
    OfDpaFlowContext fc = {
        .of_dpa = world_private(world),
        .in_pport = pport,
        .iov = iov_copy,
        .iovcnt = iovcnt + 2,
    };

    of_dpa_flow_pkt_parse(&fc, iov, iovcnt);
    of_dpa_flow_ig_tbl(&fc, ROCKER_OF_DPA_TABLE_ID_INGRESS_PORT);

    return iov_size(iov, iovcnt);
}

#define ROCKER_TUNNEL_LPORT 0x00010000

static int of_dpa_cmd_add_ig_port(OfDpaFlow *flow, RockerTlv **flow_tlvs)
{
    OfDpaFlowKey *key = &flow->key;
    OfDpaFlowKey *mask = &flow->mask;
    OfDpaFlowAction *action = &flow->action;
    bool overlay_tunnel;

    if (!flow_tlvs[ROCKER_TLV_OF_DPA_IN_PPORT] ||
        !flow_tlvs[ROCKER_TLV_OF_DPA_GOTO_TABLE_ID]) {
        return -ROCKER_EINVAL;
    }

    key->tbl_id = ROCKER_OF_DPA_TABLE_ID_INGRESS_PORT;
    key->width = FLOW_KEY_WIDTH(tbl_id);

    key->in_pport = rocker_tlv_get_le32(flow_tlvs[ROCKER_TLV_OF_DPA_IN_PPORT]);
    if (flow_tlvs[ROCKER_TLV_OF_DPA_IN_PPORT_MASK]) {
        mask->in_pport =
            rocker_tlv_get_le32(flow_tlvs[ROCKER_TLV_OF_DPA_IN_PPORT_MASK]);
    }

    overlay_tunnel = !!(key->in_pport & ROCKER_TUNNEL_LPORT);

    action->goto_tbl =
        rocker_tlv_get_le16(flow_tlvs[ROCKER_TLV_OF_DPA_GOTO_TABLE_ID]);

    if (!overlay_tunnel && action->goto_tbl != ROCKER_OF_DPA_TABLE_ID_VLAN) {
        return -ROCKER_EINVAL;
    }

    if (overlay_tunnel && action->goto_tbl != ROCKER_OF_DPA_TABLE_ID_BRIDGING) {
        return -ROCKER_EINVAL;
    }

    return ROCKER_OK;
}

static int of_dpa_cmd_add_vlan(OfDpaFlow *flow, RockerTlv **flow_tlvs)
{
    OfDpaFlowKey *key = &flow->key;
    OfDpaFlowKey *mask = &flow->mask;
    OfDpaFlowAction *action = &flow->action;
    uint32_t port;
    bool untagged;

    if (!flow_tlvs[ROCKER_TLV_OF_DPA_IN_PPORT] ||
        !flow_tlvs[ROCKER_TLV_OF_DPA_VLAN_ID]) {
        DPRINTF("Must give in_pport and vlan_id to install VLAN tbl entry\n");
        return -ROCKER_EINVAL;
    }

    key->tbl_id = ROCKER_OF_DPA_TABLE_ID_VLAN;
    key->width = FLOW_KEY_WIDTH(eth.vlan_id);

    key->in_pport = rocker_tlv_get_le32(flow_tlvs[ROCKER_TLV_OF_DPA_IN_PPORT]);
    if (!fp_port_from_pport(key->in_pport, &port)) {
        DPRINTF("in_pport (%d) not a front-panel port\n", key->in_pport);
        return -ROCKER_EINVAL;
    }
    mask->in_pport = 0xffffffff;

    key->eth.vlan_id = rocker_tlv_get_u16(flow_tlvs[ROCKER_TLV_OF_DPA_VLAN_ID]);

    if (flow_tlvs[ROCKER_TLV_OF_DPA_VLAN_ID_MASK]) {
        mask->eth.vlan_id =
            rocker_tlv_get_u16(flow_tlvs[ROCKER_TLV_OF_DPA_VLAN_ID_MASK]);
    }

    if (key->eth.vlan_id) {
        untagged = false; /* filtering */
    } else {
        untagged = true;
    }

    if (flow_tlvs[ROCKER_TLV_OF_DPA_GOTO_TABLE_ID]) {
        action->goto_tbl =
            rocker_tlv_get_le16(flow_tlvs[ROCKER_TLV_OF_DPA_GOTO_TABLE_ID]);
        if (action->goto_tbl != ROCKER_OF_DPA_TABLE_ID_TERMINATION_MAC) {
            DPRINTF("Goto tbl (%d) must be TERM_MAC\n", action->goto_tbl);
            return -ROCKER_EINVAL;
        }
    }

    if (untagged) {
        if (!flow_tlvs[ROCKER_TLV_OF_DPA_NEW_VLAN_ID]) {
            DPRINTF("Must specify new vlan_id if untagged\n");
            return -ROCKER_EINVAL;
        }
        action->apply.new_vlan_id =
            rocker_tlv_get_u16(flow_tlvs[ROCKER_TLV_OF_DPA_NEW_VLAN_ID]);
        if (1 > ntohs(action->apply.new_vlan_id) ||
            ntohs(action->apply.new_vlan_id) > 4095) {
            DPRINTF("New vlan_id (%d) must be between 1 and 4095\n",
                    ntohs(action->apply.new_vlan_id));
            return -ROCKER_EINVAL;
        }
    }

    return ROCKER_OK;
}

static int of_dpa_cmd_add_term_mac(OfDpaFlow *flow, RockerTlv **flow_tlvs)
{
    OfDpaFlowKey *key = &flow->key;
    OfDpaFlowKey *mask = &flow->mask;
    OfDpaFlowAction *action = &flow->action;
    const MACAddr ipv4_mcast = { .a = { 0x01, 0x00, 0x5e, 0x00, 0x00, 0x00 } };
    const MACAddr ipv4_mask =  { .a = { 0xff, 0xff, 0xff, 0x80, 0x00, 0x00 } };
    const MACAddr ipv6_mcast = { .a = { 0x33, 0x33, 0x00, 0x00, 0x00, 0x00 } };
    const MACAddr ipv6_mask =  { .a = { 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 } };
    uint32_t port;
    bool unicast = false;
    bool multicast = false;

    if (!flow_tlvs[ROCKER_TLV_OF_DPA_IN_PPORT] ||
        !flow_tlvs[ROCKER_TLV_OF_DPA_IN_PPORT_MASK] ||
        !flow_tlvs[ROCKER_TLV_OF_DPA_ETHERTYPE] ||
        !flow_tlvs[ROCKER_TLV_OF_DPA_DST_MAC] ||
        !flow_tlvs[ROCKER_TLV_OF_DPA_DST_MAC_MASK] ||
        !flow_tlvs[ROCKER_TLV_OF_DPA_VLAN_ID] ||
        !flow_tlvs[ROCKER_TLV_OF_DPA_VLAN_ID_MASK]) {
        return -ROCKER_EINVAL;
    }

    key->tbl_id = ROCKER_OF_DPA_TABLE_ID_TERMINATION_MAC;
    key->width = FLOW_KEY_WIDTH(eth.type);

    key->in_pport = rocker_tlv_get_le32(flow_tlvs[ROCKER_TLV_OF_DPA_IN_PPORT]);
    if (!fp_port_from_pport(key->in_pport, &port)) {
        return -ROCKER_EINVAL;
    }
    mask->in_pport =
        rocker_tlv_get_le32(flow_tlvs[ROCKER_TLV_OF_DPA_IN_PPORT_MASK]);

    key->eth.type = rocker_tlv_get_u16(flow_tlvs[ROCKER_TLV_OF_DPA_ETHERTYPE]);
    if (key->eth.type != htons(0x0800) && key->eth.type != htons(0x86dd)) {
        return -ROCKER_EINVAL;
    }
    mask->eth.type = htons(0xffff);

    memcpy(key->eth.dst.a,
           rocker_tlv_data(flow_tlvs[ROCKER_TLV_OF_DPA_DST_MAC]),
           sizeof(key->eth.dst.a));
    memcpy(mask->eth.dst.a,
           rocker_tlv_data(flow_tlvs[ROCKER_TLV_OF_DPA_DST_MAC_MASK]),
           sizeof(mask->eth.dst.a));

    if ((key->eth.dst.a[0] & 0x01) == 0x00) {
        unicast = true;
    }

    /* only two wildcard rules are acceptable for IPv4 and IPv6 multicast */
    if (memcmp(key->eth.dst.a, ipv4_mcast.a, sizeof(key->eth.dst.a)) == 0 &&
        memcmp(mask->eth.dst.a, ipv4_mask.a, sizeof(mask->eth.dst.a)) == 0) {
        multicast = true;
    }
    if (memcmp(key->eth.dst.a, ipv6_mcast.a, sizeof(key->eth.dst.a)) == 0 &&
        memcmp(mask->eth.dst.a, ipv6_mask.a, sizeof(mask->eth.dst.a)) == 0) {
        multicast = true;
    }

    if (!unicast && !multicast) {
        return -ROCKER_EINVAL;
    }

    key->eth.vlan_id = rocker_tlv_get_u16(flow_tlvs[ROCKER_TLV_OF_DPA_VLAN_ID]);
    mask->eth.vlan_id =
        rocker_tlv_get_u16(flow_tlvs[ROCKER_TLV_OF_DPA_VLAN_ID_MASK]);

    if (flow_tlvs[ROCKER_TLV_OF_DPA_GOTO_TABLE_ID]) {
        action->goto_tbl =
            rocker_tlv_get_le16(flow_tlvs[ROCKER_TLV_OF_DPA_GOTO_TABLE_ID]);

        if (action->goto_tbl != ROCKER_OF_DPA_TABLE_ID_UNICAST_ROUTING &&
            action->goto_tbl != ROCKER_OF_DPA_TABLE_ID_MULTICAST_ROUTING) {
            return -ROCKER_EINVAL;
        }

        if (unicast &&
            action->goto_tbl != ROCKER_OF_DPA_TABLE_ID_UNICAST_ROUTING) {
            return -ROCKER_EINVAL;
        }

        if (multicast &&
            action->goto_tbl != ROCKER_OF_DPA_TABLE_ID_MULTICAST_ROUTING) {
            return -ROCKER_EINVAL;
        }
    }

    if (flow_tlvs[ROCKER_TLV_OF_DPA_COPY_CPU_ACTION]) {
        action->apply.copy_to_cpu =
            rocker_tlv_get_u8(flow_tlvs[ROCKER_TLV_OF_DPA_COPY_CPU_ACTION]);
    }

    return ROCKER_OK;
}

static int of_dpa_cmd_add_bridging(OfDpaFlow *flow, RockerTlv **flow_tlvs)
{
    OfDpaFlowKey *key = &flow->key;
    OfDpaFlowKey *mask = &flow->mask;
    OfDpaFlowAction *action = &flow->action;
    bool unicast = false;
    bool dst_mac = false;
    bool dst_mac_mask = false;
    enum {
        BRIDGING_MODE_UNKNOWN,
        BRIDGING_MODE_VLAN_UCAST,
        BRIDGING_MODE_VLAN_MCAST,
        BRIDGING_MODE_VLAN_DFLT,
        BRIDGING_MODE_TUNNEL_UCAST,
        BRIDGING_MODE_TUNNEL_MCAST,
        BRIDGING_MODE_TUNNEL_DFLT,
    } mode = BRIDGING_MODE_UNKNOWN;

    key->tbl_id = ROCKER_OF_DPA_TABLE_ID_BRIDGING;

    if (flow_tlvs[ROCKER_TLV_OF_DPA_VLAN_ID]) {
        key->eth.vlan_id =
            rocker_tlv_get_u16(flow_tlvs[ROCKER_TLV_OF_DPA_VLAN_ID]);
        mask->eth.vlan_id = 0xffff;
        key->width = FLOW_KEY_WIDTH(eth.vlan_id);
    }

    if (flow_tlvs[ROCKER_TLV_OF_DPA_TUNNEL_ID]) {
        key->tunnel_id =
            rocker_tlv_get_le32(flow_tlvs[ROCKER_TLV_OF_DPA_TUNNEL_ID]);
        mask->tunnel_id = 0xffffffff;
        key->width = FLOW_KEY_WIDTH(tunnel_id);
    }

    /* can't do VLAN bridging and tunnel bridging at same time */
    if (key->eth.vlan_id && key->tunnel_id) {
        DPRINTF("can't do VLAN bridging and tunnel bridging at same time\n");
        return -ROCKER_EINVAL;
    }

    if (flow_tlvs[ROCKER_TLV_OF_DPA_DST_MAC]) {
        memcpy(key->eth.dst.a,
               rocker_tlv_data(flow_tlvs[ROCKER_TLV_OF_DPA_DST_MAC]),
               sizeof(key->eth.dst.a));
        key->width = FLOW_KEY_WIDTH(eth.dst);
        dst_mac = true;
        unicast = (key->eth.dst.a[0] & 0x01) == 0x00;
    }

    if (flow_tlvs[ROCKER_TLV_OF_DPA_DST_MAC_MASK]) {
        memcpy(mask->eth.dst.a,
               rocker_tlv_data(flow_tlvs[ROCKER_TLV_OF_DPA_DST_MAC_MASK]),
               sizeof(mask->eth.dst.a));
        key->width = FLOW_KEY_WIDTH(eth.dst);
        dst_mac_mask = true;
    } else if (flow_tlvs[ROCKER_TLV_OF_DPA_DST_MAC]) {
        memcpy(mask->eth.dst.a, ff_mac.a, sizeof(mask->eth.dst.a));
    }

    if (key->eth.vlan_id) {
        if (dst_mac && !dst_mac_mask) {
            mode = unicast ? BRIDGING_MODE_VLAN_UCAST :
                             BRIDGING_MODE_VLAN_MCAST;
        } else if ((dst_mac && dst_mac_mask) || !dst_mac) {
            mode = BRIDGING_MODE_VLAN_DFLT;
        }
    } else if (key->tunnel_id) {
        if (dst_mac && !dst_mac_mask) {
            mode = unicast ? BRIDGING_MODE_TUNNEL_UCAST :
                             BRIDGING_MODE_TUNNEL_MCAST;
        } else if ((dst_mac && dst_mac_mask) || !dst_mac) {
            mode = BRIDGING_MODE_TUNNEL_DFLT;
        }
    }

    if (mode == BRIDGING_MODE_UNKNOWN) {
        DPRINTF("Unknown bridging mode\n");
        return -ROCKER_EINVAL;
    }

    if (flow_tlvs[ROCKER_TLV_OF_DPA_GOTO_TABLE_ID]) {
        action->goto_tbl =
            rocker_tlv_get_le16(flow_tlvs[ROCKER_TLV_OF_DPA_GOTO_TABLE_ID]);
        if (action->goto_tbl != ROCKER_OF_DPA_TABLE_ID_ACL_POLICY) {
            DPRINTF("Briding goto tbl must be ACL policy\n");
            return -ROCKER_EINVAL;
        }
    }

    if (flow_tlvs[ROCKER_TLV_OF_DPA_GROUP_ID]) {
        action->write.group_id =
            rocker_tlv_get_le32(flow_tlvs[ROCKER_TLV_OF_DPA_GROUP_ID]);
        switch (mode) {
        case BRIDGING_MODE_VLAN_UCAST:
            if (ROCKER_GROUP_TYPE_GET(action->write.group_id) !=
                ROCKER_OF_DPA_GROUP_TYPE_L2_INTERFACE) {
                DPRINTF("Bridging mode vlan ucast needs L2 "
                        "interface group (0x%08x)\n",
                        action->write.group_id);
                return -ROCKER_EINVAL;
            }
            break;
        case BRIDGING_MODE_VLAN_MCAST:
            if (ROCKER_GROUP_TYPE_GET(action->write.group_id) !=
                ROCKER_OF_DPA_GROUP_TYPE_L2_MCAST) {
                DPRINTF("Bridging mode vlan mcast needs L2 "
                        "mcast group (0x%08x)\n",
                        action->write.group_id);
                return -ROCKER_EINVAL;
            }
            break;
        case BRIDGING_MODE_VLAN_DFLT:
            if (ROCKER_GROUP_TYPE_GET(action->write.group_id) !=
                ROCKER_OF_DPA_GROUP_TYPE_L2_FLOOD) {
                DPRINTF("Bridging mode vlan dflt needs L2 "
                        "flood group (0x%08x)\n",
                        action->write.group_id);
                return -ROCKER_EINVAL;
            }
            break;
        case BRIDGING_MODE_TUNNEL_MCAST:
            if (ROCKER_GROUP_TYPE_GET(action->write.group_id) !=
                ROCKER_OF_DPA_GROUP_TYPE_L2_OVERLAY) {
                DPRINTF("Bridging mode tunnel mcast needs L2 "
                        "overlay group (0x%08x)\n",
                        action->write.group_id);
                return -ROCKER_EINVAL;
            }
            break;
        case BRIDGING_MODE_TUNNEL_DFLT:
            if (ROCKER_GROUP_TYPE_GET(action->write.group_id) !=
                ROCKER_OF_DPA_GROUP_TYPE_L2_OVERLAY) {
                DPRINTF("Bridging mode tunnel dflt needs L2 "
                        "overlay group (0x%08x)\n",
                        action->write.group_id);
                return -ROCKER_EINVAL;
            }
            break;
        default:
            return -ROCKER_EINVAL;
        }
    }

    if (flow_tlvs[ROCKER_TLV_OF_DPA_TUNNEL_LPORT]) {
        action->write.tun_log_lport =
            rocker_tlv_get_le32(flow_tlvs[ROCKER_TLV_OF_DPA_TUNNEL_LPORT]);
        if (mode != BRIDGING_MODE_TUNNEL_UCAST) {
            DPRINTF("Have tunnel logical port but not "
                    "in bridging tunnel mode\n");
            return -ROCKER_EINVAL;
        }
    }

    if (flow_tlvs[ROCKER_TLV_OF_DPA_COPY_CPU_ACTION]) {
        action->apply.copy_to_cpu =
            rocker_tlv_get_u8(flow_tlvs[ROCKER_TLV_OF_DPA_COPY_CPU_ACTION]);
    }

    return ROCKER_OK;
}

static int of_dpa_cmd_add_unicast_routing(OfDpaFlow *flow,
                                          RockerTlv **flow_tlvs)
{
    OfDpaFlowKey *key = &flow->key;
    OfDpaFlowKey *mask = &flow->mask;
    OfDpaFlowAction *action = &flow->action;
    enum {
        UNICAST_ROUTING_MODE_UNKNOWN,
        UNICAST_ROUTING_MODE_IPV4,
        UNICAST_ROUTING_MODE_IPV6,
    } mode = UNICAST_ROUTING_MODE_UNKNOWN;
    uint8_t type;

    if (!flow_tlvs[ROCKER_TLV_OF_DPA_ETHERTYPE]) {
        return -ROCKER_EINVAL;
    }

    key->tbl_id = ROCKER_OF_DPA_TABLE_ID_UNICAST_ROUTING;
    key->width = FLOW_KEY_WIDTH(ipv6.addr.dst);

    key->eth.type = rocker_tlv_get_u16(flow_tlvs[ROCKER_TLV_OF_DPA_ETHERTYPE]);
    switch (ntohs(key->eth.type)) {
    case 0x0800:
        mode = UNICAST_ROUTING_MODE_IPV4;
        break;
    case 0x86dd:
        mode = UNICAST_ROUTING_MODE_IPV6;
        break;
    default:
        return -ROCKER_EINVAL;
    }
    mask->eth.type = htons(0xffff);

    switch (mode) {
    case UNICAST_ROUTING_MODE_IPV4:
        if (!flow_tlvs[ROCKER_TLV_OF_DPA_DST_IP]) {
            return -ROCKER_EINVAL;
        }
        key->ipv4.addr.dst =
            rocker_tlv_get_u32(flow_tlvs[ROCKER_TLV_OF_DPA_DST_IP]);
        if (ipv4_addr_is_multicast(key->ipv4.addr.dst)) {
            return -ROCKER_EINVAL;
        }
        flow->lpm = of_dpa_mask2prefix(htonl(0xffffffff));
        if (flow_tlvs[ROCKER_TLV_OF_DPA_DST_IP_MASK]) {
            mask->ipv4.addr.dst =
                rocker_tlv_get_u32(flow_tlvs[ROCKER_TLV_OF_DPA_DST_IP_MASK]);
            flow->lpm = of_dpa_mask2prefix(mask->ipv4.addr.dst);
        }
        break;
    case UNICAST_ROUTING_MODE_IPV6:
        if (!flow_tlvs[ROCKER_TLV_OF_DPA_DST_IPV6]) {
            return -ROCKER_EINVAL;
        }
        memcpy(&key->ipv6.addr.dst,
               rocker_tlv_data(flow_tlvs[ROCKER_TLV_OF_DPA_DST_IPV6]),
               sizeof(key->ipv6.addr.dst));
        if (ipv6_addr_is_multicast(&key->ipv6.addr.dst)) {
            return -ROCKER_EINVAL;
        }
        if (flow_tlvs[ROCKER_TLV_OF_DPA_DST_IPV6_MASK]) {
            memcpy(&mask->ipv6.addr.dst,
                   rocker_tlv_data(flow_tlvs[ROCKER_TLV_OF_DPA_DST_IPV6_MASK]),
                   sizeof(mask->ipv6.addr.dst));
        }
        break;
    default:
        return -ROCKER_EINVAL;
    }

    if (flow_tlvs[ROCKER_TLV_OF_DPA_GOTO_TABLE_ID]) {
        action->goto_tbl =
            rocker_tlv_get_le16(flow_tlvs[ROCKER_TLV_OF_DPA_GOTO_TABLE_ID]);
        if (action->goto_tbl != ROCKER_OF_DPA_TABLE_ID_ACL_POLICY) {
            return -ROCKER_EINVAL;
        }
    }

    if (flow_tlvs[ROCKER_TLV_OF_DPA_GROUP_ID]) {
        action->write.group_id =
            rocker_tlv_get_le32(flow_tlvs[ROCKER_TLV_OF_DPA_GROUP_ID]);
        type = ROCKER_GROUP_TYPE_GET(action->write.group_id);
        if (type != ROCKER_OF_DPA_GROUP_TYPE_L2_INTERFACE &&
            type != ROCKER_OF_DPA_GROUP_TYPE_L3_UCAST &&
            type != ROCKER_OF_DPA_GROUP_TYPE_L3_ECMP) {
            return -ROCKER_EINVAL;
        }
    }

    return ROCKER_OK;
}

static int of_dpa_cmd_add_multicast_routing(OfDpaFlow *flow,
                                            RockerTlv **flow_tlvs)
{
    OfDpaFlowKey *key = &flow->key;
    OfDpaFlowKey *mask = &flow->mask;
    OfDpaFlowAction *action = &flow->action;
    enum {
        MULTICAST_ROUTING_MODE_UNKNOWN,
        MULTICAST_ROUTING_MODE_IPV4,
        MULTICAST_ROUTING_MODE_IPV6,
    } mode = MULTICAST_ROUTING_MODE_UNKNOWN;

    if (!flow_tlvs[ROCKER_TLV_OF_DPA_ETHERTYPE] ||
        !flow_tlvs[ROCKER_TLV_OF_DPA_VLAN_ID]) {
        return -ROCKER_EINVAL;
    }

    key->tbl_id = ROCKER_OF_DPA_TABLE_ID_MULTICAST_ROUTING;
    key->width = FLOW_KEY_WIDTH(ipv6.addr.dst);

    key->eth.type = rocker_tlv_get_u16(flow_tlvs[ROCKER_TLV_OF_DPA_ETHERTYPE]);
    switch (ntohs(key->eth.type)) {
    case 0x0800:
        mode = MULTICAST_ROUTING_MODE_IPV4;
        break;
    case 0x86dd:
        mode = MULTICAST_ROUTING_MODE_IPV6;
        break;
    default:
        return -ROCKER_EINVAL;
    }

    key->eth.vlan_id = rocker_tlv_get_u16(flow_tlvs[ROCKER_TLV_OF_DPA_VLAN_ID]);

    switch (mode) {
    case MULTICAST_ROUTING_MODE_IPV4:

        if (flow_tlvs[ROCKER_TLV_OF_DPA_SRC_IP]) {
            key->ipv4.addr.src =
                rocker_tlv_get_u32(flow_tlvs[ROCKER_TLV_OF_DPA_SRC_IP]);
        }

        if (flow_tlvs[ROCKER_TLV_OF_DPA_SRC_IP_MASK]) {
            mask->ipv4.addr.src =
                rocker_tlv_get_u32(flow_tlvs[ROCKER_TLV_OF_DPA_SRC_IP_MASK]);
        }

        if (!flow_tlvs[ROCKER_TLV_OF_DPA_SRC_IP]) {
            if (mask->ipv4.addr.src != 0) {
                return -ROCKER_EINVAL;
            }
        }

        if (!flow_tlvs[ROCKER_TLV_OF_DPA_DST_IP]) {
            return -ROCKER_EINVAL;
        }

        key->ipv4.addr.dst =
            rocker_tlv_get_u32(flow_tlvs[ROCKER_TLV_OF_DPA_DST_IP]);
        if (!ipv4_addr_is_multicast(key->ipv4.addr.dst)) {
            return -ROCKER_EINVAL;
        }

        break;

    case MULTICAST_ROUTING_MODE_IPV6:

        if (flow_tlvs[ROCKER_TLV_OF_DPA_SRC_IPV6]) {
            memcpy(&key->ipv6.addr.src,
                   rocker_tlv_data(flow_tlvs[ROCKER_TLV_OF_DPA_SRC_IPV6]),
                   sizeof(key->ipv6.addr.src));
        }

        if (flow_tlvs[ROCKER_TLV_OF_DPA_SRC_IPV6_MASK]) {
            memcpy(&mask->ipv6.addr.src,
                   rocker_tlv_data(flow_tlvs[ROCKER_TLV_OF_DPA_SRC_IPV6_MASK]),
                   sizeof(mask->ipv6.addr.src));
        }

        if (!flow_tlvs[ROCKER_TLV_OF_DPA_SRC_IPV6]) {
            if (mask->ipv6.addr.src.addr32[0] != 0 &&
                mask->ipv6.addr.src.addr32[1] != 0 &&
                mask->ipv6.addr.src.addr32[2] != 0 &&
                mask->ipv6.addr.src.addr32[3] != 0) {
                return -ROCKER_EINVAL;
            }
        }

        if (!flow_tlvs[ROCKER_TLV_OF_DPA_DST_IPV6]) {
            return -ROCKER_EINVAL;
        }

        memcpy(&key->ipv6.addr.dst,
               rocker_tlv_data(flow_tlvs[ROCKER_TLV_OF_DPA_DST_IPV6]),
               sizeof(key->ipv6.addr.dst));
        if (!ipv6_addr_is_multicast(&key->ipv6.addr.dst)) {
            return -ROCKER_EINVAL;
        }

        break;

    default:
        return -ROCKER_EINVAL;
    }

    if (flow_tlvs[ROCKER_TLV_OF_DPA_GOTO_TABLE_ID]) {
        action->goto_tbl =
            rocker_tlv_get_le16(flow_tlvs[ROCKER_TLV_OF_DPA_GOTO_TABLE_ID]);
        if (action->goto_tbl != ROCKER_OF_DPA_TABLE_ID_ACL_POLICY) {
            return -ROCKER_EINVAL;
        }
    }

    if (flow_tlvs[ROCKER_TLV_OF_DPA_GROUP_ID]) {
        action->write.group_id =
            rocker_tlv_get_le32(flow_tlvs[ROCKER_TLV_OF_DPA_GROUP_ID]);
        if (ROCKER_GROUP_TYPE_GET(action->write.group_id) !=
            ROCKER_OF_DPA_GROUP_TYPE_L3_MCAST) {
            return -ROCKER_EINVAL;
        }
        action->write.vlan_id = key->eth.vlan_id;
    }

    return ROCKER_OK;
}

static int of_dpa_cmd_add_acl_ip(OfDpaFlowKey *key, OfDpaFlowKey *mask,
                                 RockerTlv **flow_tlvs)
{
    key->width = FLOW_KEY_WIDTH(ip.tos);

    key->ip.proto = 0;
    key->ip.tos = 0;
    mask->ip.proto = 0;
    mask->ip.tos = 0;

    if (flow_tlvs[ROCKER_TLV_OF_DPA_IP_PROTO]) {
        key->ip.proto =
            rocker_tlv_get_u8(flow_tlvs[ROCKER_TLV_OF_DPA_IP_PROTO]);
    }
    if (flow_tlvs[ROCKER_TLV_OF_DPA_IP_PROTO_MASK]) {
        mask->ip.proto =
            rocker_tlv_get_u8(flow_tlvs[ROCKER_TLV_OF_DPA_IP_PROTO_MASK]);
    }
    if (flow_tlvs[ROCKER_TLV_OF_DPA_IP_DSCP]) {
        key->ip.tos =
            rocker_tlv_get_u8(flow_tlvs[ROCKER_TLV_OF_DPA_IP_DSCP]);
    }
    if (flow_tlvs[ROCKER_TLV_OF_DPA_IP_DSCP_MASK]) {
        mask->ip.tos =
            rocker_tlv_get_u8(flow_tlvs[ROCKER_TLV_OF_DPA_IP_DSCP_MASK]);
    }
    if (flow_tlvs[ROCKER_TLV_OF_DPA_IP_ECN]) {
        key->ip.tos |=
            rocker_tlv_get_u8(flow_tlvs[ROCKER_TLV_OF_DPA_IP_ECN]) << 6;
    }
    if (flow_tlvs[ROCKER_TLV_OF_DPA_IP_ECN_MASK]) {
        mask->ip.tos |=
            rocker_tlv_get_u8(flow_tlvs[ROCKER_TLV_OF_DPA_IP_ECN_MASK]) << 6;
    }

    return ROCKER_OK;
}

static int of_dpa_cmd_add_acl(OfDpaFlow *flow, RockerTlv **flow_tlvs)
{
    OfDpaFlowKey *key = &flow->key;
    OfDpaFlowKey *mask = &flow->mask;
    OfDpaFlowAction *action = &flow->action;
    enum {
        ACL_MODE_UNKNOWN,
        ACL_MODE_IPV4_VLAN,
        ACL_MODE_IPV6_VLAN,
        ACL_MODE_IPV4_TENANT,
        ACL_MODE_IPV6_TENANT,
        ACL_MODE_NON_IP_VLAN,
        ACL_MODE_NON_IP_TENANT,
        ACL_MODE_ANY_VLAN,
        ACL_MODE_ANY_TENANT,
    } mode = ACL_MODE_UNKNOWN;
    int err = ROCKER_OK;

    if (!flow_tlvs[ROCKER_TLV_OF_DPA_IN_PPORT] ||
        !flow_tlvs[ROCKER_TLV_OF_DPA_ETHERTYPE]) {
        return -ROCKER_EINVAL;
    }

    if (flow_tlvs[ROCKER_TLV_OF_DPA_VLAN_ID] &&
        flow_tlvs[ROCKER_TLV_OF_DPA_TUNNEL_ID]) {
        return -ROCKER_EINVAL;
    }

    key->tbl_id = ROCKER_OF_DPA_TABLE_ID_ACL_POLICY;
    key->width = FLOW_KEY_WIDTH(eth.type);

    key->in_pport = rocker_tlv_get_le32(flow_tlvs[ROCKER_TLV_OF_DPA_IN_PPORT]);
    if (flow_tlvs[ROCKER_TLV_OF_DPA_IN_PPORT_MASK]) {
        mask->in_pport =
            rocker_tlv_get_le32(flow_tlvs[ROCKER_TLV_OF_DPA_IN_PPORT_MASK]);
    }

    if (flow_tlvs[ROCKER_TLV_OF_DPA_SRC_MAC]) {
        memcpy(key->eth.src.a,
               rocker_tlv_data(flow_tlvs[ROCKER_TLV_OF_DPA_SRC_MAC]),
               sizeof(key->eth.src.a));
    }

    if (flow_tlvs[ROCKER_TLV_OF_DPA_SRC_MAC_MASK]) {
        memcpy(mask->eth.src.a,
               rocker_tlv_data(flow_tlvs[ROCKER_TLV_OF_DPA_SRC_MAC_MASK]),
               sizeof(mask->eth.src.a));
    }

    if (flow_tlvs[ROCKER_TLV_OF_DPA_DST_MAC]) {
        memcpy(key->eth.dst.a,
               rocker_tlv_data(flow_tlvs[ROCKER_TLV_OF_DPA_DST_MAC]),
               sizeof(key->eth.dst.a));
    }

    if (flow_tlvs[ROCKER_TLV_OF_DPA_DST_MAC_MASK]) {
        memcpy(mask->eth.dst.a,
               rocker_tlv_data(flow_tlvs[ROCKER_TLV_OF_DPA_DST_MAC_MASK]),
               sizeof(mask->eth.dst.a));
    }

    key->eth.type = rocker_tlv_get_u16(flow_tlvs[ROCKER_TLV_OF_DPA_ETHERTYPE]);
    if (key->eth.type) {
        mask->eth.type = 0xffff;
    }

    if (flow_tlvs[ROCKER_TLV_OF_DPA_VLAN_ID]) {
        key->eth.vlan_id =
            rocker_tlv_get_u16(flow_tlvs[ROCKER_TLV_OF_DPA_VLAN_ID]);
    }

    if (flow_tlvs[ROCKER_TLV_OF_DPA_VLAN_ID_MASK]) {
        mask->eth.vlan_id =
            rocker_tlv_get_u16(flow_tlvs[ROCKER_TLV_OF_DPA_VLAN_ID_MASK]);
    }

    switch (ntohs(key->eth.type)) {
    case 0x0000:
        mode = (key->eth.vlan_id) ? ACL_MODE_ANY_VLAN : ACL_MODE_ANY_TENANT;
        break;
    case 0x0800:
        mode = (key->eth.vlan_id) ? ACL_MODE_IPV4_VLAN : ACL_MODE_IPV4_TENANT;
        break;
    case 0x86dd:
        mode = (key->eth.vlan_id) ? ACL_MODE_IPV6_VLAN : ACL_MODE_IPV6_TENANT;
        break;
    default:
        mode = (key->eth.vlan_id) ? ACL_MODE_NON_IP_VLAN :
                                    ACL_MODE_NON_IP_TENANT;
        break;
    }

    /* XXX only supporting VLAN modes for now */
    if (mode != ACL_MODE_IPV4_VLAN &&
        mode != ACL_MODE_IPV6_VLAN &&
        mode != ACL_MODE_NON_IP_VLAN &&
        mode != ACL_MODE_ANY_VLAN) {
        return -ROCKER_EINVAL;
    }

    switch (ntohs(key->eth.type)) {
    case 0x0800:
    case 0x86dd:
        err = of_dpa_cmd_add_acl_ip(key, mask, flow_tlvs);
        break;
    }

    if (err) {
        return err;
    }

    if (flow_tlvs[ROCKER_TLV_OF_DPA_GROUP_ID]) {
        action->write.group_id =
            rocker_tlv_get_le32(flow_tlvs[ROCKER_TLV_OF_DPA_GROUP_ID]);
    }

    if (flow_tlvs[ROCKER_TLV_OF_DPA_COPY_CPU_ACTION]) {
        action->apply.copy_to_cpu =
            rocker_tlv_get_u8(flow_tlvs[ROCKER_TLV_OF_DPA_COPY_CPU_ACTION]);
    }

    return ROCKER_OK;
}

static int of_dpa_cmd_flow_add_mod(OfDpa *of_dpa, OfDpaFlow *flow,
                                   RockerTlv **flow_tlvs)
{
    enum rocker_of_dpa_table_id tbl;
    int err = ROCKER_OK;

    if (!flow_tlvs[ROCKER_TLV_OF_DPA_TABLE_ID] ||
        !flow_tlvs[ROCKER_TLV_OF_DPA_PRIORITY] ||
        !flow_tlvs[ROCKER_TLV_OF_DPA_HARDTIME]) {
        return -ROCKER_EINVAL;
    }

    tbl = rocker_tlv_get_le16(flow_tlvs[ROCKER_TLV_OF_DPA_TABLE_ID]);
    flow->priority = rocker_tlv_get_le32(flow_tlvs[ROCKER_TLV_OF_DPA_PRIORITY]);
    flow->hardtime = rocker_tlv_get_le32(flow_tlvs[ROCKER_TLV_OF_DPA_HARDTIME]);

    if (flow_tlvs[ROCKER_TLV_OF_DPA_IDLETIME]) {
        if (tbl == ROCKER_OF_DPA_TABLE_ID_INGRESS_PORT ||
            tbl == ROCKER_OF_DPA_TABLE_ID_VLAN ||
            tbl == ROCKER_OF_DPA_TABLE_ID_TERMINATION_MAC) {
            return -ROCKER_EINVAL;
        }
        flow->idletime =
            rocker_tlv_get_le32(flow_tlvs[ROCKER_TLV_OF_DPA_IDLETIME]);
    }

    switch (tbl) {
    case ROCKER_OF_DPA_TABLE_ID_INGRESS_PORT:
        err = of_dpa_cmd_add_ig_port(flow, flow_tlvs);
        break;
    case ROCKER_OF_DPA_TABLE_ID_VLAN:
        err = of_dpa_cmd_add_vlan(flow, flow_tlvs);
        break;
    case ROCKER_OF_DPA_TABLE_ID_TERMINATION_MAC:
        err = of_dpa_cmd_add_term_mac(flow, flow_tlvs);
        break;
    case ROCKER_OF_DPA_TABLE_ID_BRIDGING:
        err = of_dpa_cmd_add_bridging(flow, flow_tlvs);
        break;
    case ROCKER_OF_DPA_TABLE_ID_UNICAST_ROUTING:
        err = of_dpa_cmd_add_unicast_routing(flow, flow_tlvs);
        break;
    case ROCKER_OF_DPA_TABLE_ID_MULTICAST_ROUTING:
        err = of_dpa_cmd_add_multicast_routing(flow, flow_tlvs);
        break;
    case ROCKER_OF_DPA_TABLE_ID_ACL_POLICY:
        err = of_dpa_cmd_add_acl(flow, flow_tlvs);
        break;
    }

    return err;
}

static int of_dpa_cmd_flow_add(OfDpa *of_dpa, uint64_t cookie,
                               RockerTlv **flow_tlvs)
{
    OfDpaFlow *flow = of_dpa_flow_find(of_dpa, cookie);
    int err = ROCKER_OK;

    if (flow) {
        return -ROCKER_EEXIST;
    }

    flow = of_dpa_flow_alloc(cookie);
    if (!flow) {
        return -ROCKER_ENOMEM;
    }

    err = of_dpa_cmd_flow_add_mod(of_dpa, flow, flow_tlvs);
    if (err) {
        g_free(flow);
        return err;
    }

    return of_dpa_flow_add(of_dpa, flow);
}

static int of_dpa_cmd_flow_mod(OfDpa *of_dpa, uint64_t cookie,
                               RockerTlv **flow_tlvs)
{
    OfDpaFlow *flow = of_dpa_flow_find(of_dpa, cookie);

    if (!flow) {
        return -ROCKER_ENOENT;
    }

    return of_dpa_cmd_flow_add_mod(of_dpa, flow, flow_tlvs);
}

static int of_dpa_cmd_flow_del(OfDpa *of_dpa, uint64_t cookie)
{
    OfDpaFlow *flow = of_dpa_flow_find(of_dpa, cookie);

    if (!flow) {
        return -ROCKER_ENOENT;
    }

    of_dpa_flow_del(of_dpa, flow);

    return ROCKER_OK;
}

static int of_dpa_cmd_flow_get_stats(OfDpa *of_dpa, uint64_t cookie,
                                     struct desc_info *info, char *buf)
{
    OfDpaFlow *flow = of_dpa_flow_find(of_dpa, cookie);
    size_t tlv_size;
    int64_t now = qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) / 1000;
    int pos;

    if (!flow) {
        return -ROCKER_ENOENT;
    }

    tlv_size = rocker_tlv_total_size(sizeof(uint32_t)) +  /* duration */
               rocker_tlv_total_size(sizeof(uint64_t)) +  /* rx_pkts */
               rocker_tlv_total_size(sizeof(uint64_t));   /* tx_ptks */

    if (tlv_size > desc_buf_size(info)) {
        return -ROCKER_EMSGSIZE;
    }

    pos = 0;
    rocker_tlv_put_le32(buf, &pos, ROCKER_TLV_OF_DPA_FLOW_STAT_DURATION,
                        (int32_t)(now - flow->stats.install_time));
    rocker_tlv_put_le64(buf, &pos, ROCKER_TLV_OF_DPA_FLOW_STAT_RX_PKTS,
                        flow->stats.rx_pkts);
    rocker_tlv_put_le64(buf, &pos, ROCKER_TLV_OF_DPA_FLOW_STAT_TX_PKTS,
                        flow->stats.tx_pkts);

    return desc_set_buf(info, tlv_size);
}

static int of_dpa_flow_cmd(OfDpa *of_dpa, struct desc_info *info,
                           char *buf, uint16_t cmd,
                           RockerTlv **flow_tlvs)
{
    uint64_t cookie;

    if (!flow_tlvs[ROCKER_TLV_OF_DPA_COOKIE]) {
        return -ROCKER_EINVAL;
    }

    cookie = rocker_tlv_get_le64(flow_tlvs[ROCKER_TLV_OF_DPA_COOKIE]);

    switch (cmd) {
    case ROCKER_TLV_CMD_TYPE_OF_DPA_FLOW_ADD:
        return of_dpa_cmd_flow_add(of_dpa, cookie, flow_tlvs);
    case ROCKER_TLV_CMD_TYPE_OF_DPA_FLOW_MOD:
        return of_dpa_cmd_flow_mod(of_dpa, cookie, flow_tlvs);
    case ROCKER_TLV_CMD_TYPE_OF_DPA_FLOW_DEL:
        return of_dpa_cmd_flow_del(of_dpa, cookie);
    case ROCKER_TLV_CMD_TYPE_OF_DPA_FLOW_GET_STATS:
        return of_dpa_cmd_flow_get_stats(of_dpa, cookie, info, buf);
    }

    return -ROCKER_ENOTSUP;
}

static int of_dpa_cmd_add_l2_interface(OfDpaGroup *group,
                                       RockerTlv **group_tlvs)
{
    if (!group_tlvs[ROCKER_TLV_OF_DPA_OUT_PPORT] ||
        !group_tlvs[ROCKER_TLV_OF_DPA_POP_VLAN]) {
        return -ROCKER_EINVAL;
    }

    group->l2_interface.out_pport =
        rocker_tlv_get_le32(group_tlvs[ROCKER_TLV_OF_DPA_OUT_PPORT]);
    group->l2_interface.pop_vlan =
        rocker_tlv_get_u8(group_tlvs[ROCKER_TLV_OF_DPA_POP_VLAN]);

    return ROCKER_OK;
}

static int of_dpa_cmd_add_l2_rewrite(OfDpa *of_dpa, OfDpaGroup *group,
                                     RockerTlv **group_tlvs)
{
    OfDpaGroup *l2_interface_group;

    if (!group_tlvs[ROCKER_TLV_OF_DPA_GROUP_ID_LOWER]) {
        return -ROCKER_EINVAL;
    }

    group->l2_rewrite.group_id =
        rocker_tlv_get_le32(group_tlvs[ROCKER_TLV_OF_DPA_GROUP_ID_LOWER]);

    l2_interface_group = of_dpa_group_find(of_dpa, group->l2_rewrite.group_id);
    if (!l2_interface_group ||
        ROCKER_GROUP_TYPE_GET(l2_interface_group->id) !=
                              ROCKER_OF_DPA_GROUP_TYPE_L2_INTERFACE) {
        DPRINTF("l2 rewrite group needs a valid l2 interface group\n");
        return -ROCKER_EINVAL;
    }

    if (group_tlvs[ROCKER_TLV_OF_DPA_SRC_MAC]) {
        memcpy(group->l2_rewrite.src_mac.a,
               rocker_tlv_data(group_tlvs[ROCKER_TLV_OF_DPA_SRC_MAC]),
               sizeof(group->l2_rewrite.src_mac.a));
    }

    if (group_tlvs[ROCKER_TLV_OF_DPA_DST_MAC]) {
        memcpy(group->l2_rewrite.dst_mac.a,
               rocker_tlv_data(group_tlvs[ROCKER_TLV_OF_DPA_DST_MAC]),
               sizeof(group->l2_rewrite.dst_mac.a));
    }

    if (group_tlvs[ROCKER_TLV_OF_DPA_VLAN_ID]) {
        group->l2_rewrite.vlan_id =
            rocker_tlv_get_u16(group_tlvs[ROCKER_TLV_OF_DPA_VLAN_ID]);
        if (ROCKER_GROUP_VLAN_GET(l2_interface_group->id) !=
            (ntohs(group->l2_rewrite.vlan_id) & VLAN_VID_MASK)) {
            DPRINTF("Set VLAN ID must be same as L2 interface group\n");
            return -ROCKER_EINVAL;
        }
    }

    return ROCKER_OK;
}

static int of_dpa_cmd_add_l2_flood(OfDpa *of_dpa, OfDpaGroup *group,
                                   RockerTlv **group_tlvs)
{
    OfDpaGroup *l2_group;
    RockerTlv **tlvs;
    int err;
    int i;

    if (!group_tlvs[ROCKER_TLV_OF_DPA_GROUP_COUNT] ||
        !group_tlvs[ROCKER_TLV_OF_DPA_GROUP_IDS]) {
        return -ROCKER_EINVAL;
    }

    group->l2_flood.group_count =
        rocker_tlv_get_le16(group_tlvs[ROCKER_TLV_OF_DPA_GROUP_COUNT]);

    tlvs = g_new0(RockerTlv *, group->l2_flood.group_count + 1);
    if (!tlvs) {
        return -ROCKER_ENOMEM;
    }

    g_free(group->l2_flood.group_ids);
    group->l2_flood.group_ids =
        g_new0(uint32_t, group->l2_flood.group_count);
    if (!group->l2_flood.group_ids) {
        err = -ROCKER_ENOMEM;
        goto err_out;
    }

    rocker_tlv_parse_nested(tlvs, group->l2_flood.group_count,
                            group_tlvs[ROCKER_TLV_OF_DPA_GROUP_IDS]);

    for (i = 0; i < group->l2_flood.group_count; i++) {
        group->l2_flood.group_ids[i] = rocker_tlv_get_le32(tlvs[i + 1]);
    }

    /* All of the L2 interface groups referenced by the L2 flood
     * must have same VLAN
     */

    for (i = 0; i < group->l2_flood.group_count; i++) {
        l2_group = of_dpa_group_find(of_dpa, group->l2_flood.group_ids[i]);
        if (!l2_group) {
            continue;
        }
        if ((ROCKER_GROUP_TYPE_GET(l2_group->id) ==
             ROCKER_OF_DPA_GROUP_TYPE_L2_INTERFACE) &&
            (ROCKER_GROUP_VLAN_GET(l2_group->id) !=
             ROCKER_GROUP_VLAN_GET(group->id))) {
            DPRINTF("l2 interface group 0x%08x VLAN doesn't match l2 "
                    "flood group 0x%08x\n",
                    group->l2_flood.group_ids[i], group->id);
            err = -ROCKER_EINVAL;
            goto err_out;
        }
    }

    g_free(tlvs);
    return ROCKER_OK;

err_out:
    group->l2_flood.group_count = 0;
    g_free(group->l2_flood.group_ids);
    g_free(tlvs);

    return err;
}

static int of_dpa_cmd_add_l3_unicast(OfDpaGroup *group, RockerTlv **group_tlvs)
{
    if (!group_tlvs[ROCKER_TLV_OF_DPA_GROUP_ID_LOWER]) {
        return -ROCKER_EINVAL;
    }

    group->l3_unicast.group_id =
        rocker_tlv_get_le32(group_tlvs[ROCKER_TLV_OF_DPA_GROUP_ID_LOWER]);

    if (group_tlvs[ROCKER_TLV_OF_DPA_SRC_MAC]) {
        memcpy(group->l3_unicast.src_mac.a,
               rocker_tlv_data(group_tlvs[ROCKER_TLV_OF_DPA_SRC_MAC]),
               sizeof(group->l3_unicast.src_mac.a));
    }

    if (group_tlvs[ROCKER_TLV_OF_DPA_DST_MAC]) {
        memcpy(group->l3_unicast.dst_mac.a,
               rocker_tlv_data(group_tlvs[ROCKER_TLV_OF_DPA_DST_MAC]),
               sizeof(group->l3_unicast.dst_mac.a));
    }

    if (group_tlvs[ROCKER_TLV_OF_DPA_VLAN_ID]) {
        group->l3_unicast.vlan_id =
            rocker_tlv_get_u16(group_tlvs[ROCKER_TLV_OF_DPA_VLAN_ID]);
    }

    if (group_tlvs[ROCKER_TLV_OF_DPA_TTL_CHECK]) {
        group->l3_unicast.ttl_check =
            rocker_tlv_get_u8(group_tlvs[ROCKER_TLV_OF_DPA_TTL_CHECK]);
    }

    return ROCKER_OK;
}

static int of_dpa_cmd_group_do(OfDpa *of_dpa, uint32_t group_id,
                               OfDpaGroup *group, RockerTlv **group_tlvs)
{
    uint8_t type = ROCKER_GROUP_TYPE_GET(group_id);

    switch (type) {
    case ROCKER_OF_DPA_GROUP_TYPE_L2_INTERFACE:
        return of_dpa_cmd_add_l2_interface(group, group_tlvs);
    case ROCKER_OF_DPA_GROUP_TYPE_L2_REWRITE:
        return of_dpa_cmd_add_l2_rewrite(of_dpa, group, group_tlvs);
    case ROCKER_OF_DPA_GROUP_TYPE_L2_FLOOD:
    /* Treat L2 multicast group same as a L2 flood group */
    case ROCKER_OF_DPA_GROUP_TYPE_L2_MCAST:
        return of_dpa_cmd_add_l2_flood(of_dpa, group, group_tlvs);
    case ROCKER_OF_DPA_GROUP_TYPE_L3_UCAST:
        return of_dpa_cmd_add_l3_unicast(group, group_tlvs);
    }

    return -ROCKER_ENOTSUP;
}

static int of_dpa_cmd_group_add(OfDpa *of_dpa, uint32_t group_id,
                                RockerTlv **group_tlvs)
{
    OfDpaGroup *group = of_dpa_group_find(of_dpa, group_id);
    int err;

    if (group) {
        return -ROCKER_EEXIST;
    }

    group = of_dpa_group_alloc(group_id);
    if (!group) {
        return -ROCKER_ENOMEM;
    }

    err = of_dpa_cmd_group_do(of_dpa, group_id, group, group_tlvs);
    if (err) {
        goto err_cmd_add;
    }

    err = of_dpa_group_add(of_dpa, group);
    if (err) {
        goto err_cmd_add;
    }

    return ROCKER_OK;

err_cmd_add:
    g_free(group);
    return err;
}

static int of_dpa_cmd_group_mod(OfDpa *of_dpa, uint32_t group_id,
                                RockerTlv **group_tlvs)
{
    OfDpaGroup *group = of_dpa_group_find(of_dpa, group_id);

    if (!group) {
        return -ROCKER_ENOENT;
    }

    return of_dpa_cmd_group_do(of_dpa, group_id, group, group_tlvs);
}

static int of_dpa_cmd_group_del(OfDpa *of_dpa, uint32_t group_id)
{
    OfDpaGroup *group = of_dpa_group_find(of_dpa, group_id);

    if (!group) {
        return -ROCKER_ENOENT;
    }

    return of_dpa_group_del(of_dpa, group);
}

static int of_dpa_cmd_group_get_stats(OfDpa *of_dpa, uint32_t group_id,
                                      struct desc_info *info, char *buf)
{
    return -ROCKER_ENOTSUP;
}

static int of_dpa_group_cmd(OfDpa *of_dpa, struct desc_info *info,
                            char *buf, uint16_t cmd, RockerTlv **group_tlvs)
{
    uint32_t group_id;

    if (!group_tlvs[ROCKER_TLV_OF_DPA_GROUP_ID]) {
        return -ROCKER_EINVAL;
    }

    group_id = rocker_tlv_get_le32(group_tlvs[ROCKER_TLV_OF_DPA_GROUP_ID]);

    switch (cmd) {
    case ROCKER_TLV_CMD_TYPE_OF_DPA_GROUP_ADD:
        return of_dpa_cmd_group_add(of_dpa, group_id, group_tlvs);
    case ROCKER_TLV_CMD_TYPE_OF_DPA_GROUP_MOD:
        return of_dpa_cmd_group_mod(of_dpa, group_id, group_tlvs);
    case ROCKER_TLV_CMD_TYPE_OF_DPA_GROUP_DEL:
        return of_dpa_cmd_group_del(of_dpa, group_id);
    case ROCKER_TLV_CMD_TYPE_OF_DPA_GROUP_GET_STATS:
        return of_dpa_cmd_group_get_stats(of_dpa, group_id, info, buf);
    }

    return -ROCKER_ENOTSUP;
}

static int of_dpa_cmd(World *world, struct desc_info *info,
                      char *buf, uint16_t cmd, RockerTlv *cmd_info_tlv)
{
    OfDpa *of_dpa = world_private(world);
    RockerTlv *tlvs[ROCKER_TLV_OF_DPA_MAX + 1];

    rocker_tlv_parse_nested(tlvs, ROCKER_TLV_OF_DPA_MAX, cmd_info_tlv);

    switch (cmd) {
    case ROCKER_TLV_CMD_TYPE_OF_DPA_FLOW_ADD:
    case ROCKER_TLV_CMD_TYPE_OF_DPA_FLOW_MOD:
    case ROCKER_TLV_CMD_TYPE_OF_DPA_FLOW_DEL:
    case ROCKER_TLV_CMD_TYPE_OF_DPA_FLOW_GET_STATS:
        return of_dpa_flow_cmd(of_dpa, info, buf, cmd, tlvs);
    case ROCKER_TLV_CMD_TYPE_OF_DPA_GROUP_ADD:
    case ROCKER_TLV_CMD_TYPE_OF_DPA_GROUP_MOD:
    case ROCKER_TLV_CMD_TYPE_OF_DPA_GROUP_DEL:
    case ROCKER_TLV_CMD_TYPE_OF_DPA_GROUP_GET_STATS:
        return of_dpa_group_cmd(of_dpa, info, buf, cmd, tlvs);
    }

    return -ROCKER_ENOTSUP;
}

static gboolean rocker_int64_equal(gconstpointer v1, gconstpointer v2)
{
    return *((const uint64_t *)v1) == *((const uint64_t *)v2);
}

static guint rocker_int64_hash(gconstpointer v)
{
    return (guint)*(const uint64_t *)v;
}

static int of_dpa_init(World *world)
{
    OfDpa *of_dpa = world_private(world);

    of_dpa->world = world;

    of_dpa->flow_tbl = g_hash_table_new_full(rocker_int64_hash,
                                             rocker_int64_equal,
                                             NULL, g_free);
    if (!of_dpa->flow_tbl) {
        return -ENOMEM;
    }

    of_dpa->group_tbl = g_hash_table_new_full(g_int_hash, g_int_equal,
                                              NULL, g_free);
    if (!of_dpa->group_tbl) {
        goto err_group_tbl;
    }

    /* XXX hardcode some artificial table max values */
    of_dpa->flow_tbl_max_size = 100;
    of_dpa->group_tbl_max_size = 100;

    return 0;

err_group_tbl:
    g_hash_table_destroy(of_dpa->flow_tbl);
    return -ENOMEM;
}

static void of_dpa_uninit(World *world)
{
    OfDpa *of_dpa = world_private(world);

    g_hash_table_destroy(of_dpa->group_tbl);
    g_hash_table_destroy(of_dpa->flow_tbl);
}

struct of_dpa_flow_fill_context {
    RockerOfDpaFlowList *list;
    uint32_t tbl_id;
};

static void of_dpa_flow_fill(void *cookie, void *value, void *user_data)
{
    struct of_dpa_flow *flow = value;
    struct of_dpa_flow_key *key = &flow->key;
    struct of_dpa_flow_key *mask = &flow->mask;
    struct of_dpa_flow_fill_context *flow_context = user_data;
    RockerOfDpaFlowList *new;
    RockerOfDpaFlow *nflow;
    RockerOfDpaFlowKey *nkey;
    RockerOfDpaFlowMask *nmask;
    RockerOfDpaFlowAction *naction;

    if (flow_context->tbl_id != -1 &&
        flow_context->tbl_id != key->tbl_id) {
        return;
    }

    new = g_malloc0(sizeof(*new));
    nflow = new->value = g_malloc0(sizeof(*nflow));
    nkey = nflow->key = g_malloc0(sizeof(*nkey));
    nmask = nflow->mask = g_malloc0(sizeof(*nmask));
    naction = nflow->action = g_malloc0(sizeof(*naction));

    nflow->cookie = flow->cookie;
    nflow->hits = flow->stats.hits;
    nkey->priority = flow->priority;
    nkey->tbl_id = key->tbl_id;

    if (key->in_pport || mask->in_pport) {
        nkey->has_in_pport = true;
        nkey->in_pport = key->in_pport;
    }

    if (nkey->has_in_pport && mask->in_pport != 0xffffffff) {
        nmask->has_in_pport = true;
        nmask->in_pport = mask->in_pport;
    }

    if (key->eth.vlan_id || mask->eth.vlan_id) {
        nkey->has_vlan_id = true;
        nkey->vlan_id = ntohs(key->eth.vlan_id);
    }

    if (nkey->has_vlan_id && mask->eth.vlan_id != 0xffff) {
        nmask->has_vlan_id = true;
        nmask->vlan_id = ntohs(mask->eth.vlan_id);
    }

    if (key->tunnel_id || mask->tunnel_id) {
        nkey->has_tunnel_id = true;
        nkey->tunnel_id = key->tunnel_id;
    }

    if (nkey->has_tunnel_id && mask->tunnel_id != 0xffffffff) {
        nmask->has_tunnel_id = true;
        nmask->tunnel_id = mask->tunnel_id;
    }

    if (memcmp(key->eth.src.a, zero_mac.a, ETH_ALEN) ||
        memcmp(mask->eth.src.a, zero_mac.a, ETH_ALEN)) {
        nkey->has_eth_src = true;
        nkey->eth_src = qemu_mac_strdup_printf(key->eth.src.a);
    }

    if (nkey->has_eth_src && memcmp(mask->eth.src.a, ff_mac.a, ETH_ALEN)) {
        nmask->has_eth_src = true;
        nmask->eth_src = qemu_mac_strdup_printf(mask->eth.src.a);
    }

    if (memcmp(key->eth.dst.a, zero_mac.a, ETH_ALEN) ||
        memcmp(mask->eth.dst.a, zero_mac.a, ETH_ALEN)) {
        nkey->has_eth_dst = true;
        nkey->eth_dst = qemu_mac_strdup_printf(key->eth.dst.a);
    }

    if (nkey->has_eth_dst && memcmp(mask->eth.dst.a, ff_mac.a, ETH_ALEN)) {
        nmask->has_eth_dst = true;
        nmask->eth_dst = qemu_mac_strdup_printf(mask->eth.dst.a);
    }

    if (key->eth.type) {

        nkey->has_eth_type = true;
        nkey->eth_type = ntohs(key->eth.type);

        switch (ntohs(key->eth.type)) {
        case 0x0800:
        case 0x86dd:
            if (key->ip.proto || mask->ip.proto) {
                nkey->has_ip_proto = true;
                nkey->ip_proto = key->ip.proto;
            }
            if (nkey->has_ip_proto && mask->ip.proto != 0xff) {
                nmask->has_ip_proto = true;
                nmask->ip_proto = mask->ip.proto;
            }
            if (key->ip.tos || mask->ip.tos) {
                nkey->has_ip_tos = true;
                nkey->ip_tos = key->ip.tos;
            }
            if (nkey->has_ip_tos && mask->ip.tos != 0xff) {
                nmask->has_ip_tos = true;
                nmask->ip_tos = mask->ip.tos;
            }
            break;
        }

        switch (ntohs(key->eth.type)) {
        case 0x0800:
            if (key->ipv4.addr.dst || mask->ipv4.addr.dst) {
                char *dst = inet_ntoa(*(struct in_addr *)&key->ipv4.addr.dst);
                int dst_len = of_dpa_mask2prefix(mask->ipv4.addr.dst);
                nkey->has_ip_dst = true;
                nkey->ip_dst = g_strdup_printf("%s/%d", dst, dst_len);
            }
            break;
        }
    }

    if (flow->action.goto_tbl) {
        naction->has_goto_tbl = true;
        naction->goto_tbl = flow->action.goto_tbl;
    }

    if (flow->action.write.group_id) {
        naction->has_group_id = true;
        naction->group_id = flow->action.write.group_id;
    }

    if (flow->action.apply.new_vlan_id) {
        naction->has_new_vlan_id = true;
        naction->new_vlan_id = flow->action.apply.new_vlan_id;
    }

    new->next = flow_context->list;
    flow_context->list = new;
}

RockerOfDpaFlowList *qmp_query_rocker_of_dpa_flows(const char *name,
                                                   bool has_tbl_id,
                                                   uint32_t tbl_id,
                                                   Error **errp)
{
    struct rocker *r;
    struct world *w;
    struct of_dpa *of_dpa;
    struct of_dpa_flow_fill_context fill_context = {
        .list = NULL,
        .tbl_id = tbl_id,
    };

    r = rocker_find(name);
    if (!r) {
        error_setg(errp, "rocker %s not found", name);
        return NULL;
    }

    w = rocker_get_world(r, ROCKER_WORLD_TYPE_OF_DPA);
    if (!w) {
        error_setg(errp, "rocker %s doesn't have OF-DPA world", name);
        return NULL;
    }

    of_dpa = world_private(w);

    g_hash_table_foreach(of_dpa->flow_tbl, of_dpa_flow_fill, &fill_context);

    return fill_context.list;
}

struct of_dpa_group_fill_context {
    RockerOfDpaGroupList *list;
    uint8_t type;
};

static void of_dpa_group_fill(void *key, void *value, void *user_data)
{
    struct of_dpa_group *group = value;
    struct of_dpa_group_fill_context *flow_context = user_data;
    RockerOfDpaGroupList *new;
    RockerOfDpaGroup *ngroup;
    struct uint32List *id;
    int i;

    if (flow_context->type != 9 &&
        flow_context->type != ROCKER_GROUP_TYPE_GET(group->id)) {
        return;
    }

    new = g_malloc0(sizeof(*new));
    ngroup = new->value = g_malloc0(sizeof(*ngroup));

    ngroup->id = group->id;

    ngroup->type = ROCKER_GROUP_TYPE_GET(group->id);

    switch (ngroup->type) {
    case ROCKER_OF_DPA_GROUP_TYPE_L2_INTERFACE:
        ngroup->has_vlan_id = true;
        ngroup->vlan_id = ROCKER_GROUP_VLAN_GET(group->id);
        ngroup->has_pport = true;
        ngroup->pport = ROCKER_GROUP_PORT_GET(group->id);
        ngroup->has_out_pport = true;
        ngroup->out_pport = group->l2_interface.out_pport;
        ngroup->has_pop_vlan = true;
        ngroup->pop_vlan = group->l2_interface.pop_vlan;
        break;
    case ROCKER_OF_DPA_GROUP_TYPE_L2_REWRITE:
        ngroup->has_index = true;
        ngroup->index = ROCKER_GROUP_INDEX_LONG_GET(group->id);
        ngroup->has_group_id = true;
        ngroup->group_id = group->l2_rewrite.group_id;
        if (group->l2_rewrite.vlan_id) {
            ngroup->has_set_vlan_id = true;
            ngroup->set_vlan_id = ntohs(group->l2_rewrite.vlan_id);
        }
        if (memcmp(group->l2_rewrite.src_mac.a, zero_mac.a, ETH_ALEN)) {
            ngroup->has_set_eth_src = true;
            ngroup->set_eth_src =
                qemu_mac_strdup_printf(group->l2_rewrite.src_mac.a);
        }
        if (memcmp(group->l2_rewrite.dst_mac.a, zero_mac.a, ETH_ALEN)) {
            ngroup->has_set_eth_dst = true;
            ngroup->set_eth_dst =
                qemu_mac_strdup_printf(group->l2_rewrite.dst_mac.a);
        }
        break;
    case ROCKER_OF_DPA_GROUP_TYPE_L2_FLOOD:
    case ROCKER_OF_DPA_GROUP_TYPE_L2_MCAST:
        ngroup->has_vlan_id = true;
        ngroup->vlan_id = ROCKER_GROUP_VLAN_GET(group->id);
        ngroup->has_index = true;
        ngroup->index = ROCKER_GROUP_INDEX_GET(group->id);
        for (i = 0; i < group->l2_flood.group_count; i++) {
            ngroup->has_group_ids = true;
            id = g_malloc0(sizeof(*id));
            id->value = group->l2_flood.group_ids[i];
            id->next = ngroup->group_ids;
            ngroup->group_ids = id;
        }
        break;
    case ROCKER_OF_DPA_GROUP_TYPE_L3_UCAST:
        ngroup->has_index = true;
        ngroup->index = ROCKER_GROUP_INDEX_LONG_GET(group->id);
        ngroup->has_group_id = true;
        ngroup->group_id = group->l3_unicast.group_id;
        if (group->l3_unicast.vlan_id) {
            ngroup->has_set_vlan_id = true;
            ngroup->set_vlan_id = ntohs(group->l3_unicast.vlan_id);
        }
        if (memcmp(group->l3_unicast.src_mac.a, zero_mac.a, ETH_ALEN)) {
            ngroup->has_set_eth_src = true;
            ngroup->set_eth_src =
                qemu_mac_strdup_printf(group->l3_unicast.src_mac.a);
        }
        if (memcmp(group->l3_unicast.dst_mac.a, zero_mac.a, ETH_ALEN)) {
            ngroup->has_set_eth_dst = true;
            ngroup->set_eth_dst =
                qemu_mac_strdup_printf(group->l3_unicast.dst_mac.a);
        }
        if (group->l3_unicast.ttl_check) {
            ngroup->has_ttl_check = true;
            ngroup->ttl_check = group->l3_unicast.ttl_check;
        }
        break;
    }

    new->next = flow_context->list;
    flow_context->list = new;
}

RockerOfDpaGroupList *qmp_query_rocker_of_dpa_groups(const char *name,
                                                     bool has_type,
                                                     uint8_t type,
                                                     Error **errp)
{
    struct rocker *r;
    struct world *w;
    struct of_dpa *of_dpa;
    struct of_dpa_group_fill_context fill_context = {
        .list = NULL,
        .type = type,
    };

    r = rocker_find(name);
    if (!r) {
        error_setg(errp, "rocker %s not found", name);
        return NULL;
    }

    w = rocker_get_world(r, ROCKER_WORLD_TYPE_OF_DPA);
    if (!w) {
        error_setg(errp, "rocker %s doesn't have OF-DPA world", name);
        return NULL;
    }

    of_dpa = world_private(w);

    g_hash_table_foreach(of_dpa->group_tbl, of_dpa_group_fill, &fill_context);

    return fill_context.list;
}

static WorldOps of_dpa_ops = {
    .name = "ofdpa",
    .init = of_dpa_init,
    .uninit = of_dpa_uninit,
    .ig = of_dpa_ig,
    .cmd = of_dpa_cmd,
};

World *of_dpa_world_alloc(Rocker *r)
{
    return world_alloc(r, sizeof(OfDpa), ROCKER_WORLD_TYPE_OF_DPA, &of_dpa_ops);
}
