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 *);