From a87fe2ce5f01870a5e1a6e0c7aa03654c3b3d0a6 Mon Sep 17 00:00:00 2001 From: "Anand H. Krishnan" Date: Fri, 4 Dec 2015 11:45:48 +0530 Subject: [PATCH] FatFlow - BUG fixes A vif get/dump overwrites the same request memory for every protocol that is configured for FatFlow, resulting in some configured values not showing up in the output. TCP state machine shouldn't be applied for FatFlows since multiple flows can map to the same entry Change-Id: Ie67d7b049bd2a4de15041380c9f757dc4627f250 Partial-BUG: 1518234 --- dp-core/vr_flow.c | 16 ++++++++++++++++ dp-core/vr_interface.c | 5 ++--- dp-core/vr_proto_ip.c | 15 +++++++++++++++ include/vr_flow.h | 2 ++ 4 files changed, 35 insertions(+), 3 deletions(-) diff --git a/dp-core/vr_flow.c b/dp-core/vr_flow.c index 2cf1d52b3..7c455f63d 100644 --- a/dp-core/vr_flow.c +++ b/dp-core/vr_flow.c @@ -60,6 +60,8 @@ static void vr_flow_set_forwarding_md(struct vrouter *, struct vr_flow_entry *, static int __vr_flow_schedule_transition(struct vrouter *, struct vr_flow_entry *, unsigned int, unsigned short); +static bool vr_flow_is_fat_flow(struct vrouter *, struct vr_packet *, + struct vr_flow_entry *); struct vr_flow_entry *vr_find_flow(struct vrouter *, struct vr_flow *, uint8_t, unsigned int *); @@ -1038,6 +1040,9 @@ vr_flow_tcp_digest(struct vrouter *router, struct vr_flow_entry *flow_e, } if (tcph) { + if (vr_flow_is_fat_flow(router, pkt, flow_e)) + return; + /* * there are some optimizations here that makes the code slightly * not so frugal. For e.g.: the *_R flags are used to make sure that @@ -1225,6 +1230,17 @@ __vr_flow_forward(flow_result_t result, struct vr_packet *pkt, return forward; } +static bool +vr_flow_is_fat_flow(struct vrouter *router, struct vr_packet *pkt, + struct vr_flow_entry *fe) +{ + if (pkt->vp_type == VP_TYPE_IP) { + return vr_inet_flow_is_fat_flow(router, pkt, fe); + } + + return false; +} + fat_flow_port_mask_t vr_flow_fat_flow_lookup(struct vrouter *router, struct vr_packet *pkt, uint16_t l4_proto, uint16_t sport, uint16_t dport) diff --git a/dp-core/vr_interface.c b/dp-core/vr_interface.c index 218ae3b2b..8e55e2caa 100644 --- a/dp-core/vr_interface.c +++ b/dp-core/vr_interface.c @@ -1920,7 +1920,7 @@ __vr_interface_make_req(vr_interface_req *req, struct vr_interface *intf, { uint8_t proto; uint16_t port; - unsigned int cpu, i, j; + unsigned int cpu, i, j, k = 0; struct vr_interface_settings settings; @@ -2047,7 +2047,7 @@ __vr_interface_make_req(vr_interface_req *req, struct vr_interface *intf, for (j = 0; j < intf->vif_fat_flow_config_size[i]; j++) { port = intf->vif_fat_flow_config[i][j]; if (vif_fat_flow_port_is_set(intf, i, port)) { - req->vifr_fat_flow_protocol_port[j] = (proto << 16) | port; + req->vifr_fat_flow_protocol_port[k++] = (proto << 16) | port; } else { vr_printf("vif0/%u: FatFlow port %u in configuration," " but not in operational DB\n", @@ -2601,7 +2601,6 @@ vif_fat_flow_add(struct vr_interface *vif, vr_interface_req *req) */ for (i = 0; i < req->vifr_fat_flow_protocol_port_size; i++) { proto = VIF_FAT_FLOW_PROTOCOL(req->vifr_fat_flow_protocol_port[i]); - port = VIF_FAT_FLOW_PORT(req->vifr_fat_flow_protocol_port[i]); proto_index = vif_fat_flow_get_proto_index(proto); vif->vif_fat_flow_config_size[proto_index]++; diff --git a/dp-core/vr_proto_ip.c b/dp-core/vr_proto_ip.c index 9d0f80125..9ef5d928f 100644 --- a/dp-core/vr_proto_ip.c +++ b/dp-core/vr_proto_ip.c @@ -839,6 +839,21 @@ vr_inet_fragment_flow(struct vrouter *router, unsigned short vrf, return 0; } +bool +vr_inet_flow_is_fat_flow(struct vrouter *router, struct vr_packet *pkt, + struct vr_flow_entry *fe) +{ + if (!fe->fe_key.flow4_sport || !fe->fe_key.flow4_dport) { + if ((fe->fe_key.flow4_proto == VR_IP_PROTO_TCP) || + (fe->fe_key.flow4_proto == VR_IP_PROTO_UDP) || + (fe->fe_key.flow4_proto == VR_IP_PROTO_SCTP)) { + return true; + } + } + + return false; +} + static int vr_inet_proto_flow(struct vrouter *router, unsigned short vrf, struct vr_packet *pkt, uint16_t vlan, struct vr_ip *ip, diff --git a/include/vr_flow.h b/include/vr_flow.h index 63ed59094..53f220ca0 100644 --- a/include/vr_flow.h +++ b/include/vr_flow.h @@ -402,6 +402,8 @@ extern void vr_inet_fill_flow(struct vr_flow *, unsigned short, unsigned char *, uint8_t, uint16_t, uint16_t); extern void vr_inet6_fill_flow(struct vr_flow *, unsigned short, unsigned char *, uint8_t, uint16_t, uint16_t); +extern bool vr_inet_flow_is_fat_flow(struct vrouter *, struct vr_packet *, + struct vr_flow_entry *); extern unsigned int vr_reinject_packet(struct vr_packet *, struct vr_forwarding_md *);