diff --git a/include/tc/tc.h b/include/tc/tc.h index 600fa8ccb..da8d0dcc8 100644 --- a/include/tc/tc.h +++ b/include/tc/tc.h @@ -42,6 +42,11 @@ typedef uint32_t tc_handle_t; #define TC_ALIGNTO RTE_CACHE_LINE_SIZE #define TC_ALIGN(len) (((len) + TC_ALIGNTO-1) & ~(TC_ALIGNTO-1)) +typedef enum tc_hook_type { + TC_HOOK_EGRESS = 1, + TC_HOOK_INGRESS = 2, +} tc_hook_type_t; + /* need a wrapper to save mbuf list, * since there's no way to link mbuf by it's own elem. * (note mbuf.next if used for pkt segments. */ @@ -94,8 +99,8 @@ int tc_register_cls(struct tc_cls_ops *ops); int tc_unregister_cls(struct tc_cls_ops *ops); struct tc_cls_ops *tc_cls_ops_lookup(const char *name); -struct rte_mbuf *tc_handle_egress(struct netif_tc *tc, - struct rte_mbuf *mbuf, int *ret); +struct rte_mbuf *tc_hook(struct netif_tc *tc, struct rte_mbuf *mbuf, + tc_hook_type_t type, int *ret); static inline int64_t tc_get_ns(void) { diff --git a/src/netif.c b/src/netif.c index 90af4c829..020b1940f 100644 --- a/src/netif.c +++ b/src/netif.c @@ -2199,8 +2199,8 @@ int netif_xmit(struct rte_mbuf *mbuf, struct netif_port *dev) assert((mbuf_refcnt >= 1) && (mbuf_refcnt <= 64)); if (dev->flag & NETIF_PORT_FLAG_TC_EGRESS) { - mbuf = tc_handle_egress(netif_tc(dev), mbuf, &ret); - if (likely(!mbuf)) + mbuf = tc_hook(netif_tc(dev), mbuf, TC_HOOK_EGRESS, &ret); + if (!mbuf) return ret; } @@ -2240,6 +2240,7 @@ int netif_rcv(struct netif_port *dev, __be16 eth_type, struct rte_mbuf *mbuf) static int netif_deliver_mbuf(struct netif_port *dev, lcoreid_t cid, struct rte_mbuf *mbuf, bool pkts_from_ring) { + int ret = EDPVS_OK; struct ether_hdr *eth_hdr; assert(mbuf->port <= NETIF_MAX_PORTS); @@ -2265,8 +2266,9 @@ static int netif_deliver_mbuf(struct netif_port *dev, lcoreid_t cid, } if (!pkts_from_ring && (dev->flag & NETIF_PORT_FLAG_TC_INGRESS)) { - // TODO - // TC INGRESS HOOK + mbuf = tc_hook(netif_tc(dev), mbuf, TC_HOOK_INGRESS, &ret); + if (!mbuf) + return ret; } return netif_rcv_mbuf(dev, cid, mbuf, pkts_from_ring); diff --git a/src/tc/sch_generic.c b/src/tc/sch_generic.c index 50e2bf39b..61ac2f487 100644 --- a/src/tc/sch_generic.c +++ b/src/tc/sch_generic.c @@ -50,7 +50,11 @@ static inline int sch_dequeue_xmit(struct Qsch *sch, int *npkt) if (unlikely(!mbuf)) return 0; - netif_hard_xmit(mbuf, netif_port_get(mbuf->port)); + if (sch->flags & QSCH_F_INGRESS) + netif_rcv_mbuf(sch->tc->dev, rte_lcore_id(), mbuf, false); + else + netif_hard_xmit(mbuf, sch->tc->dev); + return sch->q.qlen; } diff --git a/src/tc/tc.c b/src/tc/tc.c index 6759ddde1..5abd9d207 100644 --- a/src/tc/tc.c +++ b/src/tc/tc.c @@ -108,20 +108,24 @@ int tc_unregister_cls(struct tc_cls_ops *ops) return EDPVS_OK; } -struct rte_mbuf *tc_handle_egress(struct netif_tc *tc, - struct rte_mbuf *mbuf, int *ret) +struct rte_mbuf *tc_hook(struct netif_tc *tc, struct rte_mbuf *mbuf, + tc_hook_type_t type, int *ret) { int err = EDPVS_OK; - struct Qsch *sch, *child_sch = NULL; + struct Qsch *sch, *child_sch; struct tc_cls *cls; struct tc_cls_result cls_res; const int max_reclassify_loop = 8; int limit = 0; assert(tc && mbuf && ret); + sch = child_sch = NULL; - /* start from egress root qsch */ - sch = tc->qsch; + /* start from root qsch */ + if (type == TC_HOOK_EGRESS) + sch = tc->qsch; + else if (type == TC_HOOK_INGRESS) + sch = tc->qsch_ingress; if (unlikely(!sch)) { *ret = EDPVS_OK; return mbuf; @@ -186,6 +190,12 @@ struct rte_mbuf *tc_handle_egress(struct netif_tc *tc, if (unlikely(!sch->ops->enqueue)) goto out; /* no need to set @ret */ + if (unlikely((sch->flags & QSCH_F_INGRESS) && type != TC_HOOK_INGRESS) || + (!(sch->flags & QSCH_F_INGRESS) && type != TC_HOOK_EGRESS)) { + RTE_LOG(WARNING, TC, "%s: classified to qsch of incorrect type\n", __func__); + goto out; + } + /* mbuf is always consumed (queued or dropped) */ err = sch->ops->enqueue(sch, mbuf); mbuf = NULL;