Skip to content

Commit

Permalink
dp_core: Introduce offloads module
Browse files Browse the repository at this point in the history
Smart nics may have ability to parse and act the Vrouter tunneled packets.

So, according to the Vrouter tunnels, aka MPLSoGRE, MPLSoUDP, and VXLAN, the
inner packet 5-tupples and the outer packet specifications, the HW can do
some actions. For example, the HW can detect MPLSoGRE packets and to do RSS
on the inner packet 5-tupples or just tag the packets based on the packet HW parser.

Using this HW feature the Vrouter parformance can be improved.

Add a Vrouter offloads module to use the described HW ability.

Partial-Bug: #1781402
Change-Id: I337dd1d25671271528be00a5fef2eebddf1b0292
Signed-off-by: matan <matan@mellanox.com>
  • Loading branch information
Trevor Patrie authored and Matan Azrad committed Nov 25, 2018
1 parent 345d67b commit b09e738
Show file tree
Hide file tree
Showing 24 changed files with 1,221 additions and 59 deletions.
1 change: 1 addition & 0 deletions Makefile
Expand Up @@ -69,6 +69,7 @@ ifneq ($(KERNELRELEASE), )
vrouter-y += dp-core/vr_vxlan.o dp-core/vr_fragment.o
vrouter-y += dp-core/vr_proto_ip6.o dp-core/vr_buildinfo.o
vrouter-y += dp-core/vr_bitmap.o dp-core/vr_qos.o
vrouter-y += dp-core/vr_offloads.o

ccflags-y += -I$(src)/include -I$(SANDESH_HEADER_PATH)/sandesh/gen-c
ccflags-y += -I$(SANDESH_EXTRA_HEADER_PATH)
Expand Down
2 changes: 2 additions & 0 deletions dp-core/vr_datapath.c
Expand Up @@ -670,6 +670,8 @@ vr_fabric_input_inline(struct vr_interface *vif, struct vr_packet *pkt,
unsigned short pull_len;
unsigned char *data, eth_dmac[VR_ETHER_ALEN];

if (vr_offload_prepare)
vr_offload_prepare(pkt, fmd);
fmd->fmd_vlan = vlan_id;
fmd->fmd_dvrf = vif->vif_vrf;

Expand Down
67 changes: 48 additions & 19 deletions dp-core/vr_flow.c
Expand Up @@ -20,6 +20,8 @@
#include "vr_ip_mtrie.h"
#include "vr_bridge.h"

#include "vr_offloads.h"

#define VR_NUM_FLOW_TABLES 1

#define VR_NUM_OFLOW_TABLES 1
Expand Down Expand Up @@ -190,6 +192,7 @@ vr_flow_reset_mirror(struct vrouter *router, struct vr_flow_entry *fe,
if (fe->fe_mme) {
vr_mirror_meta_entry_del(router, fe->fe_mme);
fe->fe_mme = NULL;
vr_offload_flow_meta_data_set(index, 0, 0, 0);
}
}
fe->fe_flags &= ~VR_FLOW_FLAG_MIRROR;
Expand Down Expand Up @@ -221,6 +224,8 @@ __vr_flow_reset_entry(struct vrouter *router, struct vr_flow_entry *fe)
fe->fe_hold_list = NULL;
fe->fe_key.flow_key_len = 0;

(void)vr_offload_flow_del(fe);

vr_flow_reset_mirror(router, fe, fe->fe_hentry.hentry_index);
fe->fe_ecmp_nh_index = -1;
fe->fe_src_nh_index = NH_DISCARD_ID;
Expand Down Expand Up @@ -804,6 +809,9 @@ vr_rflow_update_ecmp_index(struct vrouter *router, struct vr_flow_entry *fe,

rfe->fe_ecmp_nh_index = new_ecmp_index;

/* Update hardware reverse flow. */
(void)vr_offload_flow_set(rfe, fe->fe_rflow, NULL);

fmd->fmd_ecmp_src_nh_index = new_ecmp_index;

return 0;
Expand Down Expand Up @@ -1487,28 +1495,33 @@ vr_flow_lookup(struct vrouter *router, struct vr_flow *key,

pkt->vp_flags |= VP_FLAG_FLOW_SET;

flow_e = vr_find_flow(router, key, pkt->vp_type, &fe_index);
if (!flow_e) {
if (pkt->vp_nh &&
(pkt->vp_nh->nh_flags &
(NH_FLAG_RELAXED_POLICY | NH_FLAG_FLOW_LOOKUP)))
return FLOW_FORWARD;
if (!fmd->fmd_fe) {
flow_e = vr_find_flow(router, key, pkt->vp_type, &fe_index);
if (!flow_e) {
if (pkt->vp_nh &&
(pkt->vp_nh->nh_flags &
(NH_FLAG_RELAXED_POLICY | NH_FLAG_FLOW_LOOKUP)))
return FLOW_FORWARD;

if (!vr_flow_allow_new_flow(router, pkt, &drop_reason, &burst)) {
vr_pfree(pkt, drop_reason);
return FLOW_CONSUMED;
}

if (!vr_flow_allow_new_flow(router, pkt, &drop_reason, &burst)) {
vr_pfree(pkt, drop_reason);
return FLOW_CONSUMED;
}
flow_e = vr_flow_get_free_entry(router, key, pkt->vp_type,
true, &fe_index);
if (!flow_e) {
vr_pfree(pkt, VP_DROP_FLOW_TABLE_FULL);
return FLOW_CONSUMED;
}

flow_e = vr_flow_get_free_entry(router, key, pkt->vp_type,
true, &fe_index);
if (!flow_e) {
vr_pfree(pkt, VP_DROP_FLOW_TABLE_FULL);
return FLOW_CONSUMED;
flow_e->fe_vrf = fmd->fmd_dvrf;
/* mark as hold */
vr_flow_entry_set_hold(router, flow_e, burst);
}

flow_e->fe_vrf = fmd->fmd_dvrf;
/* mark as hold */
vr_flow_entry_set_hold(router, flow_e, burst);
} else {
flow_e = fmd->fmd_fe;
fe_index = fmd->fmd_flow_index;
}

if (flow_e->fe_flags & VR_FLOW_FLAG_EVICT_CANDIDATE)
Expand Down Expand Up @@ -1865,6 +1878,13 @@ vr_flow_set_mirror(struct vrouter *router, vr_flow_req *req,
req->fr_mir_sip, req->fr_mir_sport,
req->fr_pcap_meta_data, req->fr_pcap_meta_data_size,
req->fr_mir_vrf);

if (fe->fe_mme) {
vr_offload_flow_meta_data_set(req->fr_index,
req->fr_pcap_meta_data_size,
req->fr_pcap_meta_data,
req->fr_mir_vrf);
}
}

return;
Expand Down Expand Up @@ -2229,6 +2249,7 @@ vr_flow_set(struct vrouter *router, vr_flow_req *req,
if (fe) {
if (!(modified = vr_flow_start_modify(router, fe)))
return -EBUSY;
fe_index = (unsigned int)(req->fr_index);
}

if ((ret = vr_flow_set_req_is_invalid(router, req, fe)))
Expand Down Expand Up @@ -2365,6 +2386,14 @@ vr_flow_set(struct vrouter *router, vr_flow_req *req,

ret = vr_flow_schedule_transition(router, req, fe);

/*
* offload, no need to differentiate between add and modify. Pass the
* reverse flow as well if present.
*/
if (!ret) {
vr_offload_flow_set(fe, fe_index, rfe);
}

exit_set:
if (modified && fe) {
vr_flow_stop_modify(router, fe);
Expand Down
26 changes: 26 additions & 0 deletions dp-core/vr_interface.c
Expand Up @@ -16,6 +16,7 @@
#include "vr_btable.h"
#include "vr_route.h"
#include "vr_ip_mtrie.h"
#include "vr_offloads.h"

unsigned int vr_interfaces = VR_MAX_INTERFACES;

Expand Down Expand Up @@ -2049,6 +2050,8 @@ vr_interface_delete(vr_interface_req *req, bool need_response)
if (!vif && (ret = -ENODEV))
goto del_fail;

vr_offload_interface_del(vif);

vif_delete(vif);

del_fail:
Expand Down Expand Up @@ -2284,6 +2287,10 @@ vr_interface_add(vr_interface_req *req, bool need_response)
vif = __vrouter_get_interface(router, req->vifr_idx);
if (vif) {
ret = vr_interface_change(vif, req);
/* notify hw offload of change, if enabled */
if (!ret)
ret = vr_offload_interface_add(vif);

goto generate_resp;
}

Expand Down Expand Up @@ -2432,6 +2439,14 @@ vr_interface_add(vr_interface_req *req, bool need_response)
if (ret && vif)
vif_free(vif);

/* notify hw offload of change, if enabled */
if (!ret) {
ret = vr_offload_interface_add(vif);
if (ret) {
vif_delete(vif);
vif = NULL;
}
}
generate_resp:
if (need_response)
vr_send_response(ret);
Expand Down Expand Up @@ -2518,6 +2533,7 @@ __vr_interface_make_req(vr_interface_req *req, struct vr_interface *intf,
req->vifr_transport = intf->vif_transport;
req->vifr_os_idx = intf->vif_os_idx;
req->vifr_mtu = intf->vif_mtu;
req->vifr_nh_id = intf->vif_nh_id;
if (req->vifr_mac_size && req->vifr_mac)
memcpy(req->vifr_mac, intf->vif_mac,
MINIMUM(req->vifr_mac_size, sizeof(intf->vif_mac)));
Expand Down Expand Up @@ -3060,6 +3076,12 @@ vr_interface_get(vr_interface_req *req)
mm.vr_mm_object_type[obj_cnt] = VR_DROP_STATS_OBJECT_ID;
mm.vr_mm_object[obj_cnt] = drop_resp;
obj_cnt++;

/* zero vifr_core means to sum up all the per-core stats */
vr_interface_make_req(vif_resp, vif, (unsigned)(req->vifr_core - 1));
/* adds in stats for pkts which were offloaded on NIC and does debug
comparison to check if matching entry is programmed on NIC */
ret = vr_offload_interface_get(vif_resp);
}

generate_response:
Expand Down Expand Up @@ -3117,6 +3139,10 @@ vr_interface_dump(vr_interface_req *r)
if (vif) {
/* zero vifr_core means to sum up all the per-core stats */
vr_interface_make_req(resp, vif, (unsigned)(r->vifr_core - 1));

/* let hw offload fill in relevant fields */
vr_offload_interface_get(resp);

ret = vr_message_dump_object(dumper, VR_INTERFACE_OBJECT_ID, resp);
if (ret <= 0)
break;
Expand Down
13 changes: 13 additions & 0 deletions dp-core/vr_mirror.c
Expand Up @@ -9,6 +9,7 @@
#include "vr_sandesh.h"
#include "vr_message.h"
#include "vr_mirror.h"
#include "vr_offloads.h"

struct vr_mirror_entry *
vrouter_get_mirror(unsigned int rid, unsigned int index)
Expand Down Expand Up @@ -63,6 +64,8 @@ __vr_mirror_del(struct vrouter *router, unsigned int index)
}
vrouter_put_nexthop(nh);

vr_offload_mirror_del(index);

return 0;
}

Expand Down Expand Up @@ -128,6 +131,13 @@ vr_mirror_add(vr_mirror_req *req)
if (old_nh)
vrouter_put_nexthop(old_nh);

/* if offload failed, release the newly added mirror entry.
* vrouter_put_mirror() also drops the reference on the nhop.
*/
ret = vr_offload_mirror_add(mirror, req->mirr_index);
if (ret)
__vr_mirror_del(router, req->mirr_index);

generate_resp:
vr_send_response(ret);

Expand Down Expand Up @@ -176,6 +186,7 @@ vr_mirror_dump(vr_mirror_req *r)
mirror = router->vr_mirrors[i];
if (mirror) {
vr_mirror_make_req(&req, mirror, i);
vr_offload_mirror_get(&req);
ret = vr_message_dump_object(dumper, VR_MIRROR_OBJECT_ID, &req);
if (ret <= 0)
break;
Expand Down Expand Up @@ -207,6 +218,8 @@ vr_mirror_get(vr_mirror_req *req)

if (mirror) {
vr_mirror_make_req(req, mirror, req->mirr_index);
/* Debug comparison to check if matching entry is programmed on NIC */
vr_offload_mirror_get(req);
} else
req = NULL;

Expand Down
27 changes: 22 additions & 5 deletions dp-core/vr_mpls.c
Expand Up @@ -13,6 +13,7 @@
#include "vr_bridge.h"
#include "vr_datapath.h"
#include "vr_btable.h"
#include "vr_offloads.h"

unsigned int vr_mpls_labels = VR_DEF_LABELS;

Expand Down Expand Up @@ -84,6 +85,9 @@ vr_mpls_del(vr_mpls_req *req)
goto generate_resp;
}

/* notify hw offload of change, if enabled */
vr_offload_mpls_del(req->mr_label);

ret = __vr_mpls_del(router, req->mr_label);

generate_resp:
Expand Down Expand Up @@ -131,6 +135,13 @@ vr_mpls_add(vr_mpls_req *req)
&& nh->nh_type == NH_ENCAP && !(nh->nh_flags & NH_FLAG_MCAST))
vrouter_host->hos_add_mpls(router, req->mr_label);

/* notify hw offload of change, if enabled */
if (!ret) {
ret = vr_offload_mpls_add(nh, req->mr_label);
if (ret)
__vr_mpls_del(router, req->mr_label);
}

generate_resp:
vr_send_response(ret);

Expand All @@ -145,6 +156,9 @@ vr_mpls_make_req(vr_mpls_req *req, struct vr_nexthop *nh,
req->mr_nhid = nh->nh_id;
req->mr_label = label;

/* Debug comparison to check if matching entry is programmed on NIC */
vr_offload_mpls_get(req);

return;
}

Expand Down Expand Up @@ -337,11 +351,14 @@ vr_mpls_input(struct vrouter *router, struct vr_packet *pkt,
goto dropit;
}

nh = __vrouter_get_label(router, label);
if (!nh) {
drop_reason = VP_DROP_INVALID_LABEL;
goto dropit;
}
if (!fmd->fmd_fe) {
nh = __vrouter_get_label(router, label);
if (!nh) {
drop_reason = VP_DROP_INVALID_LABEL;
goto dropit;
}
} else
nh = pkt->vp_nh;

/*
* Mark it for GRO. Diag, L2 and multicast nexthops unmark if
Expand Down
20 changes: 20 additions & 0 deletions dp-core/vr_nexthop.c
Expand Up @@ -18,6 +18,7 @@
#include "vr_route.h"
#include "vr_hash.h"
#include "vr_mirror.h"
#include "vr_offloads.h"

extern bool vr_has_to_fragment(struct vr_interface *, struct vr_packet *,
unsigned int);
Expand Down Expand Up @@ -2840,6 +2841,7 @@ vr_nexthop_delete(vr_nexthop_req *req)
if (!nh) {
ret = -EINVAL;
} else {
vr_offload_nexthop_del(nh);
vrouter_put_nexthop(nh);
nh->nh_destructor(nh);
}
Expand Down Expand Up @@ -3596,6 +3598,15 @@ vr_nexthop_add(vr_nexthop_req *req)
nh->nh_flags |= NH_FLAG_VALID;

ret = vrouter_add_nexthop(nh);

if (ret) {
nh->nh_destructor(nh);
goto generate_resp;
}
else /* notify hw offload of change, if enabled */
ret = vr_offload_nexthop_add(nh);

/* if offload failed, delete kernel entry for consistency */
if (ret)
nh->nh_destructor(nh);

Expand Down Expand Up @@ -3932,6 +3943,10 @@ vr_nexthop_get(vr_nexthop_req *req)
} else
ret = -ENOENT;

/* Debug comparison to check if matching entry is programmed on NIC */
if (!ret)
vr_offload_nexthop_get(nh, resp);

generate_response:
vr_message_response(VR_NEXTHOP_OBJECT_ID, ret < 0 ? NULL : resp, ret, false);
if (resp)
Expand Down Expand Up @@ -3970,6 +3985,10 @@ vr_nexthop_dump(vr_nexthop_req *r)

resp->h_op = SANDESH_OP_DUMP;
ret = vr_nexthop_make_req(resp, nh);

if (!ret)
vr_offload_nexthop_get(nh, resp);

if ((ret < 0) || ((ret = vr_message_dump_object(dumper,
VR_NEXTHOP_OBJECT_ID, resp)) <= 0)) {
vr_nexthop_req_destroy(resp);
Expand Down Expand Up @@ -4103,3 +4122,4 @@ vr_nexthop_init(struct vrouter *router)
{
return nh_table_init(router);
}

0 comments on commit b09e738

Please sign in to comment.