diff --git a/dp-core/vr_flow.c b/dp-core/vr_flow.c index 680365d33..6f67844ce 100644 --- a/dp-core/vr_flow.c +++ b/dp-core/vr_flow.c @@ -201,7 +201,7 @@ vr_reset_flow_entry(struct vrouter *router, struct vr_flow_entry *fe, { memset(&fe->fe_stats, 0, sizeof(fe->fe_stats)); memset(&fe->fe_hold_list, 0, sizeof(fe->fe_hold_list));; - fe->fe_key.key_len = 0; + fe->fe_key.flow_key_len = 0; fe->fe_type = VP_TYPE_NULL; memset(&fe->fe_key, 0, sizeof(fe->fe_key)); @@ -334,7 +334,7 @@ vr_find_free_entry(struct vrouter *router, struct vr_flow *key, uint8_t type, *fe_index = 0; - hash = vr_hash(key, key->key_len, 0); + hash = vr_hash(key, key->flow_key_len, 0); index = (hash % vr_flow_entries) & ~(VR_FLOW_ENTRIES_PER_BUCKET - 1); for (i = 0; i < VR_FLOW_ENTRIES_PER_BUCKET; i++) { @@ -381,8 +381,8 @@ vr_find_free_entry(struct vrouter *router, struct vr_flow *key, uint8_t type, if (fe) { fe->fe_type = type; - fe->fe_key.key_len = key->key_len; - memcpy(&fe->fe_key, key, key->key_len); + fe->fe_key.flow_key_len = key->flow_key_len; + memcpy(&fe->fe_key, key, key->flow_key_len); } } @@ -411,7 +411,7 @@ vr_flow_table_lookup(struct vr_flow *key, uint16_t type, if (flow_e && (flow_e->fe_flags & VR_FLOW_FLAG_ACTIVE) && (flow_e->fe_type == type)) { - if (!memcmp(&flow_e->fe_key, key, key->key_len)) { + if (!memcmp(&flow_e->fe_key, key, key->flow_key_len)) { *fe_index = (hash + i) % table_size; return flow_e; } @@ -429,7 +429,7 @@ vr_find_flow(struct vrouter *router, struct vr_flow *key, unsigned int hash; struct vr_flow_entry *flow_e; - hash = vr_hash(key, key->key_len, 0); + hash = vr_hash(key, key->flow_key_len, 0); /* first look in the regular flow table */ flow_e = vr_flow_table_lookup(key, type, router->vr_flow_table, @@ -642,8 +642,8 @@ vr_trap_flow(struct vrouter *router, struct vr_flow_entry *fe, default: trap_reason = AGENT_TRAP_FLOW_MISS; ta.vfta_index = index; - if (fe->fe_type == VP_TYPE_IP) - ta.vfta_nh_index = fe->fe_key.flow4_nh_id; + if ((fe->fe_type == VP_TYPE_IP) || (fe->fe_type == VP_TYPE_IP6)) + ta.vfta_nh_index = fe->fe_key.flow_nh_id; break; } @@ -783,18 +783,30 @@ __vr_flow_forward(flow_result_t result, struct vr_packet *pkt, return forward; } +static flow_result_t +__vr_flow_lookup(struct vrouter *router, struct vr_packet *pkt, + struct vr_forwarding_md *fmd) +{ + flow_result_t result = FLOW_FORWARD; + + /* Flow processig is only for untagged unicast IP packets */ + if (pkt->vp_type == VP_TYPE_IP) + result = vr_inet_flow_lookup(router, pkt, fmd); + else if (pkt->vp_type == VP_TYPE_IP6) + result = vr_inet6_flow_lookup(router, pkt, fmd); + + return result; +} + bool vr_flow_forward(struct vrouter *router, struct vr_packet *pkt, struct vr_forwarding_md *fmd) { - flow_result_t result; + flow_result_t result = FLOW_FORWARD; - /* Flow processig is only for untagged unicast IP packets */ - if ((pkt->vp_type == VP_TYPE_IP) && (!(pkt->vp_flags & VP_FLAG_MULTICAST)) + if ((!(pkt->vp_flags & VP_FLAG_MULTICAST)) && ((fmd->fmd_vlan == VLAN_ID_INVALID) || vif_is_service(pkt->vp_if))) - result = vr_inet_flow_lookup(router, pkt, fmd); - else - result = FLOW_FORWARD; + result = __vr_flow_lookup(router, pkt, fmd); return __vr_flow_forward(result, pkt, fmd); } @@ -988,10 +1000,15 @@ vr_add_flow_req(vr_flow_req *req, unsigned int *fe_index) struct vr_flow key; struct vr_flow_entry *fe; - vr_inet_fill_flow(&key, req->fr_flow_nh_id, req->fr_flow_sip, - req->fr_flow_dip, req->fr_flow_proto, - req->fr_flow_sport, req->fr_flow_dport); - type = VP_TYPE_IP; + if (req->fr_family == AF_INET6) { + type = VP_TYPE_IP6; + vr_inet6_fill_flow(&key, req->fr_flow_nh_id, req->fr_flow_ip, + req->fr_flow_proto, req->fr_flow_sport, req->fr_flow_dport); + } else { + type = VP_TYPE_IP; + vr_inet_fill_flow(&key, req->fr_flow_nh_id, req->fr_flow_ip, + req->fr_flow_proto, req->fr_flow_sport, req->fr_flow_dport); + } if (req->fr_action == VR_FLOW_ACTION_HOLD) need_hold_queue = true; @@ -1014,13 +1031,13 @@ vr_flow_req_is_invalid(struct vrouter *router, vr_flow_req *req, struct vr_flow_entry *rfe; if (fe) { - if (fe->fe_type == VP_TYPE_IP) { - if ((unsigned int)req->fr_flow_sip != fe->fe_key.flow4_sip || - (unsigned int)req->fr_flow_dip != fe->fe_key.flow4_dip || - (unsigned short)req->fr_flow_sport != fe->fe_key.flow4_sport || - (unsigned short)req->fr_flow_dport != fe->fe_key.flow4_dport|| - (unsigned short)req->fr_flow_nh_id != fe->fe_key.flow4_nh_id || - (unsigned char)req->fr_flow_proto != fe->fe_key.flow4_proto) { + if ((fe->fe_type == VP_TYPE_IP) || (fe->fe_type == VP_TYPE_IP6)) { + if (memcmp(req->fr_flow_ip, fe->fe_key.flow_ip, + 2 * VR_FLOW_IP_ADDR_SIZE(fe->fe_type)) || + (unsigned short)req->fr_flow_sport != fe->fe_key.flow_sport || + (unsigned short)req->fr_flow_dport != fe->fe_key.flow_dport|| + (unsigned short)req->fr_flow_nh_id != fe->fe_key.flow_nh_id || + (unsigned char)req->fr_flow_proto != fe->fe_key.flow_proto) { return -EBADF; } } @@ -1086,8 +1103,8 @@ vr_flow_delete(struct vrouter *router, vr_flow_req *req, struct vr_flow_entry *fe) { if (fe->fe_flags & VR_FLOW_FLAG_LINK_LOCAL) - vr_clear_link_local_port(router, AF_INET, fe->fe_key.flow4_proto, - ntohs(fe->fe_key.flow4_dport)); + vr_clear_link_local_port(router, AF_INET, fe->fe_key.flow_proto, + ntohs(fe->fe_key.flow_dport)); fe->fe_action = VR_FLOW_ACTION_DROP; vr_flow_reset_mirror(router, fe, req->fr_index); @@ -1098,7 +1115,7 @@ vr_flow_delete(struct vrouter *router, vr_flow_req *req, static void vr_flow_udp_src_port (struct vrouter *router, struct vr_flow_entry *fe) { - uint32_t hash_key[5], hashval, port_range; + uint32_t hash_key[10], hashval, port_range, hash_len; uint16_t port; if (fe->fe_udp_src_port) @@ -1109,13 +1126,12 @@ vr_flow_udp_src_port (struct vrouter *router, struct vr_flow_entry *fe) hashrnd_inited = 1; } - hash_key[0] = fe->fe_key.flow4_sip; - hash_key[1] = fe->fe_key.flow4_dip; - hash_key[2] = fe->fe_vrf; - hash_key[3] = fe->fe_key.flow4_sport; - hash_key[4] = fe->fe_key.flow4_dport; + hash_key[0] = fe->fe_vrf; + hash_key[1] = (fe->fe_key.flow_sport << 16) | fe->fe_key.flow_dport; + memcpy(&hash_key[2], fe->fe_key.flow_ip, 2*VR_FLOW_IP_ADDR_SIZE(fe->fe_type)); + hash_len = VR_FLOW_KEY_SIZE(fe->fe_type); - hashval = jhash(hash_key, 20, vr_hashrnd); + hashval = jhash(hash_key, hash_len, vr_hashrnd); port_range = VR_MUDP_PORT_RANGE_END - VR_MUDP_PORT_RANGE_START; port = (uint16_t ) (((uint64_t ) hashval * port_range) >> 32); @@ -1198,13 +1214,13 @@ vr_flow_set(struct vrouter *router, vr_flow_req *req) if (req->fr_flags & VR_FLOW_FLAG_LINK_LOCAL) { if (!(fe->fe_flags & VR_FLOW_FLAG_LINK_LOCAL)) vr_set_link_local_port(router, AF_INET, - fe->fe_key.flow4_proto, - ntohs(fe->fe_key.flow4_dport)); + fe->fe_key.flow_proto, + ntohs(fe->fe_key.flow_dport)); } else { if (fe->fe_flags & VR_FLOW_FLAG_LINK_LOCAL) vr_clear_link_local_port(router, AF_INET, - fe->fe_key.flow4_proto, - ntohs(fe->fe_key.flow4_dport)); + fe->fe_key.flow_proto, + ntohs(fe->fe_key.flow_dport)); } } diff --git a/dp-core/vr_nexthop.c b/dp-core/vr_nexthop.c index ae458fe0e..c8a039b3f 100644 --- a/dp-core/vr_nexthop.c +++ b/dp-core/vr_nexthop.c @@ -340,11 +340,9 @@ nh_vxlan_tunnel_helper(struct vr_packet *pkt, struct vr_forwarding_md *fmd, udp_src_port = fmd->fmd_udp_src_port; /* - * The UDP source port is a hash of the inner headers. For IPV6 - * the standard port is used till flow processing is done + * The UDP source port is a hash of the inner headers */ - if ((!fmd->fmd_udp_src_port) && (pkt->vp_type != VP_TYPE_IP6) && - vr_get_udp_src_port) { + if ((!fmd->fmd_udp_src_port) && vr_get_udp_src_port) { udp_src_port = vr_get_udp_src_port(pkt, fmd, fmd->fmd_dvrf); if (udp_src_port == 0) { return false; @@ -1359,11 +1357,9 @@ nh_mpls_udp_tunnel(struct vr_packet *pkt, struct vr_nexthop *nh, /* * The UDP source port is a hash of the inner IP src/dst address and - * vrf. For the IPV6 standard source port is used till flow - * procesing is done + * vrf. */ - if ((!fmd->fmd_udp_src_port) && (pkt->vp_type != VP_TYPE_IP6) && - vr_get_udp_src_port) { + if ((!fmd->fmd_udp_src_port) && vr_get_udp_src_port) { udp_src_port = vr_get_udp_src_port(pkt, fmd, fmd->fmd_dvrf); if (udp_src_port == 0) { reason = VP_DROP_PULL; @@ -1618,7 +1614,7 @@ nh_output(struct vr_packet *pkt, struct vr_nexthop *nh, return 0; } - if (pkt->vp_type == VP_TYPE_IP) { + if ((pkt->vp_type == VP_TYPE_IP) || (pkt->vp_type == VP_TYPE_IP6)) { /* * If the packet has not gone through flow lookup once * (!VP_FLAG_FLOW_SET), we need to determine whether it has to undergo diff --git a/dp-core/vr_proto_ip.c b/dp-core/vr_proto_ip.c index 4b5e085c5..667dc45ae 100644 --- a/dp-core/vr_proto_ip.c +++ b/dp-core/vr_proto_ip.c @@ -763,7 +763,7 @@ vr_inet_flow_swap(struct vr_flow *key_p) return; } -static unsigned short +unsigned short vr_inet_flow_nexthop(struct vr_packet *pkt, unsigned short vlan) { unsigned short nh_id; @@ -785,19 +785,18 @@ vr_inet_flow_nexthop(struct vr_packet *pkt, unsigned short vlan) } void -vr_inet_fill_flow(struct vr_flow *flow_p, unsigned short nh_id, - uint32_t sip, uint32_t dip, uint8_t proto, - uint16_t sport, uint16_t dport) +vr_inet_fill_flow(struct vr_flow *flow_p, unsigned short nh_id, + unsigned char *ip, uint8_t proto, uint16_t sport, uint16_t dport) { /* copy both source and destinations */ - flow_p->flow4_sip = sip; - flow_p->flow4_dip = dip; + memcpy(flow_p->flow_ip, ip, 2*VR_FLOW_IPV4_ADDR_SIZE); flow_p->flow4_proto = proto; flow_p->flow4_nh_id = nh_id; flow_p->flow4_sport = sport; flow_p->flow4_dport = dport; + flow_p->flow4_family = AF_INET; - flow_p->key_len = sizeof(struct vr_inet_flow); + flow_p->flow_key_len = VR_FLOW_IPV4_KEY_SIZE; return; } @@ -823,7 +822,7 @@ vr_inet_fragment_flow(struct vrouter *router, unsigned short vrf, vr_fragment_del(frag); nh_id = vr_inet_flow_nexthop(pkt, vlan); - vr_inet_fill_flow(flow_p, nh_id, ip->ip_saddr, ip->ip_daddr, + vr_inet_fill_flow(flow_p, nh_id, (unsigned char *)&ip->ip_saddr, ip->ip_proto, sport, dport); return 0; } @@ -863,7 +862,7 @@ vr_inet_proto_flow(struct vrouter *router, unsigned short vrf, } nh_id = vr_inet_flow_nexthop(pkt, vlan); - vr_inet_fill_flow(flow_p, nh_id, ip->ip_saddr, ip->ip_daddr, + vr_inet_fill_flow(flow_p, nh_id, (unsigned char *)&ip->ip_saddr, ip->ip_proto, sport, dport); return 0; diff --git a/dp-core/vr_proto_ip6.c b/dp-core/vr_proto_ip6.c index 52040ee53..008be4cc7 100644 --- a/dp-core/vr_proto_ip6.c +++ b/dp-core/vr_proto_ip6.c @@ -116,6 +116,99 @@ vr_icmp6_input(struct vrouter *router, struct vr_packet *pkt, return handled; } +void +vr_inet6_fill_flow(struct vr_flow *flow_p, unsigned short nh_id, + unsigned char *ip, uint8_t proto, uint16_t sport, uint16_t dport) +{ + /* copy both source and destinations */ + memcpy(flow_p->flow_ip, ip, 2*VR_FLOW_IPV6_ADDR_SIZE); + flow_p->flow6_proto = proto; + flow_p->flow6_nh_id = nh_id; + flow_p->flow6_sport = sport; + flow_p->flow6_dport = dport; + flow_p->flow6_family = AF_INET6; + + flow_p->flow_key_len = VR_FLOW_IPV6_KEY_SIZE; + + return; +} + +static int +vr_inet6_form_flow(struct vrouter *router, unsigned short vrf, + struct vr_packet *pkt, uint16_t vlan, struct vr_ip6 *ip6, + struct vr_flow *flow_p) +{ + unsigned short *t_hdr, sport, dport; + unsigned short nh_id; + + struct vr_icmp *icmph; + + /* Skip flow lookup for V6 frags */ + if (ip6->ip6_nxt == VR_IP6_PROTO_FRAG) + return 1; + + t_hdr = (unsigned short *)((char *)ip6 + sizeof(struct vr_ip6)); + if (ip6->ip6_nxt == VR_IP_PROTO_ICMP6) { + icmph = (struct vr_icmp *)t_hdr; + if ((icmph->icmp_type == VR_ICMP6_TYPE_ECHO_REQ) || + (icmph->icmp_type == VR_ICMP6_TYPE_ECHO_REPLY)) { + sport = icmph->icmp_eid; + dport = ntohs(VR_ICMP6_TYPE_ECHO_REPLY); + } else { + sport = 0; + dport = icmph->icmp_type; + } + } else { + sport = *t_hdr; + dport = *(t_hdr + 1); + } + + nh_id = vr_inet_flow_nexthop(pkt, vlan); + vr_inet6_fill_flow(flow_p, nh_id, (unsigned char *)&ip6->ip6_src, + ip6->ip6_nxt, sport, dport); + + return 0; +} + +flow_result_t +vr_inet6_flow_lookup(struct vrouter *router, struct vr_packet *pkt, + struct vr_forwarding_md *fmd) +{ + int ret; + bool lookup = false; + struct vr_flow flow, *flow_p = &flow; + struct vr_ip6 *ip6 = (struct vr_ip6 *)pkt_network_header(pkt); + + /* + * if the packet has already done one round of flow lookup, there + * is no point in doing it again, eh? + */ + if (pkt->vp_flags & VP_FLAG_FLOW_SET) + return FLOW_FORWARD; + + ret = vr_inet6_form_flow(router, fmd->fmd_dvrf, pkt, fmd->fmd_vlan, ip6, flow_p); + if (ret < 0) + return FLOW_CONSUMED; + + /* + * if the interface is policy enabled, or if somebody else (eg:nexthop) + * has requested for a policy lookup, packet has to go through a lookup + */ + if ((pkt->vp_if->vif_flags & VIF_FLAG_POLICY_ENABLED) || + (pkt->vp_flags & VP_FLAG_FLOW_GET)) { + lookup = true; + } + + + if (lookup) { + + return vr_flow_lookup(router, flow_p, pkt, fmd); + } + + return FLOW_FORWARD; +} + + int vr_ip6_input(struct vrouter *router, struct vr_packet *pkt, struct vr_forwarding_md *fmd) diff --git a/include/vr_flow.h b/include/vr_flow.h index 4b1fcb06f..b89625687 100644 --- a/include/vr_flow.h +++ b/include/vr_flow.h @@ -62,33 +62,85 @@ typedef enum { #define VR_FLOW_DR_REVERSE_SG 0x11 #define VR_FLOW_DR_REVERSE_OUT_SG 0x12 +#define VR_FLOW_IPV6_ADDR_SIZE 16 +#define VR_FLOW_IPV4_ADDR_SIZE 4 +#define VR_FLOW_IP_ADDR_SIZE(type) \ + ((type == VP_TYPE_IP6) ? VR_FLOW_IPV6_ADDR_SIZE \ + : VR_FLOW_IPV4_ADDR_SIZE) + +#define VR_FLOW_IPV6_KEY_SIZE 40 +#define VR_FLOW_IPV4_KEY_SIZE 16 +#define VR_FLOW_KEY_SIZE(type) \ + ((type == VP_TYPE_IP6) ? VR_FLOW_IPV6_KEY_SIZE \ + : VR_FLOW_IPV4_KEY_SIZE) + +#define VR_FLOW_FAMILY(type) \ + ((type == VP_TYPE_IP6) ? AF_INET6 \ + : AF_INET) struct vr_forwarding_md; +struct vr_common_flow{ + unsigned char ip_family; + unsigned char ip_proto; + unsigned short ip_nh_id; + unsigned short ip_sport; + unsigned short ip_dport; + unsigned char ip_addr[2*VR_FLOW_IPV6_ADDR_SIZE]; +} __attribute__((packed)); + + struct vr_inet_flow { + unsigned char ip4_family; + unsigned char ip4_proto; + unsigned short ip4_nh_id; unsigned short ip4_sport; unsigned short ip4_dport; - unsigned int ip4_sip; - unsigned int ip4_dip; - unsigned short ip4_nh_id; - unsigned char ip4_proto; + unsigned int ip4_sip; + unsigned int ip4_dip; +} __attribute__((packed)); + +struct vr_inet6_flow { + unsigned char ip6_family; + unsigned char ip6_proto; + unsigned short ip6_nh_id; + unsigned short ip6_sport; + unsigned short ip6_dport; + unsigned char ip6_sip[VR_FLOW_IPV6_ADDR_SIZE]; + unsigned char ip6_dip[VR_FLOW_IPV6_ADDR_SIZE]; } __attribute__((packed)); struct vr_flow { union { + struct vr_common_flow ip_key; struct vr_inet_flow ip4_key; + struct vr_inet6_flow ip6_key; } key_u; + uint32_t vr_flow_keylen; +} __attribute__((packed)); - uint8_t key_len; -}; - -#define flow4_sport key_u.ip4_key.ip4_sport -#define flow4_dport key_u.ip4_key.ip4_dport -#define flow4_sip key_u.ip4_key.ip4_sip -#define flow4_dip key_u.ip4_key.ip4_dip -#define flow4_nh_id key_u.ip4_key.ip4_nh_id -#define flow4_proto key_u.ip4_key.ip4_proto - -/* +#define flow_key_len vr_flow_keylen +#define flow_family key_u.ip_key.ip_family +#define flow_sport key_u.ip_key.ip_sport +#define flow_dport key_u.ip_key.ip_dport +#define flow_nh_id key_u.ip_key.ip_nh_id +#define flow_proto key_u.ip_key.ip_proto +#define flow_ip key_u.ip_key.ip_addr +#define flow4_family key_u.ip4_key.ip4_family +#define flow4_sip key_u.ip4_key.ip4_sip +#define flow4_dip key_u.ip4_key.ip4_dip +#define flow4_sport key_u.ip4_key.ip4_sport +#define flow4_dport key_u.ip4_key.ip4_dport +#define flow4_nh_id key_u.ip4_key.ip4_nh_id +#define flow4_proto key_u.ip4_key.ip4_proto +#define flow6_family key_u.ip6_key.ip6_family +#define flow6_sip key_u.ip6_key.ip6_sip +#define flow6_dip key_u.ip6_key.ip6_sip +#define flow6_sport key_u.ip6_key.ip6_sport +#define flow6_dport key_u.ip6_key.ip6_dport +#define flow6_nh_id key_u.ip6_key.ip6_nh_id +#define flow6_proto key_u.ip6_key.ip6_proto + +/* * Limit the number of outstanding flows in hold state. The flow rate can * be much more than what agent can handle. In such cases, to make sure that * @@ -126,7 +178,7 @@ struct vr_flow_table_info { uint32_t vfti_hold_count[0]; }; -/* +/* * flow bytes and packets are of same width. this should be * ok since agent really has to take care of overflows. this * is also better probably because processor does not have to @@ -176,7 +228,7 @@ struct vr_dummy_flow_entry { uint8_t fe_type; } __attribute__((packed)); -#define VR_FLOW_ENTRY_PACK (64 - sizeof(struct vr_dummy_flow_entry)) +#define VR_FLOW_ENTRY_PACK (128 - sizeof(struct vr_dummy_flow_entry)) /* do not change. any field positions as it might lead to incompatibility */ struct vr_flow_entry { @@ -240,6 +292,7 @@ extern bool vr_flow_forward(struct vrouter *, struct vr_packet *, struct vr_forwarding_md *); void *vr_flow_get_va(struct vrouter *, uint64_t); + unsigned int vr_flow_table_size(struct vrouter *); unsigned int vr_oflow_table_size(struct vrouter *); @@ -249,10 +302,17 @@ flow_result_t vr_flow_lookup(struct vrouter *, struct vr_flow *, flow_result_t vr_inet_flow_lookup(struct vrouter *, struct vr_packet *, struct vr_forwarding_md *); +flow_result_t vr_inet6_flow_lookup(struct vrouter *, struct vr_packet *, + struct vr_forwarding_md *); + +unsigned short +vr_inet_flow_nexthop(struct vr_packet *pkt, unsigned short vlan); extern flow_result_t vr_inet_flow_nat(struct vr_flow_entry *, struct vr_packet *, struct vr_forwarding_md *); -extern void vr_inet_fill_flow(struct vr_flow *, unsigned short, - uint32_t, uint32_t, uint8_t, uint16_t, uint16_t); +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 unsigned int vr_reinject_packet(struct vr_packet *, struct vr_forwarding_md *); diff --git a/include/vr_packet.h b/include/vr_packet.h index 897a0bf73..6f00e60e4 100644 --- a/include/vr_packet.h +++ b/include/vr_packet.h @@ -588,6 +588,8 @@ struct vr_udp { #define VR_ICMP6_TYPE_NEIGH_SOL 135 #define VR_ICMP6_TYPE_NEIGH_AD 136 +#define VR_IP6_PROTO_FRAG 44 + struct vr_icmp { uint8_t icmp_type; uint8_t icmp_code; diff --git a/sandesh/vr.sandesh b/sandesh/vr.sandesh index 6987593fa..fe50038bb 100644 --- a/sandesh/vr.sandesh +++ b/sandesh/vr.sandesh @@ -132,8 +132,8 @@ buffer sandesh vr_flow_req { 6: i32 fr_ftable_size; 7: i16 fr_ftable_dev; 8: i32 fr_rindex; - 9: i32 fr_flow_sip; - 10: i32 fr_flow_dip; + 9: i32 fr_family; + 10: list fr_flow_ip; 11: i16 fr_flow_sport; 12: i16 fr_flow_dport; 13: byte fr_flow_proto; diff --git a/utils/flow.c b/utils/flow.c index aee33375d..e132a813a 100644 --- a/utils/flow.c +++ b/utils/flow.c @@ -143,7 +143,7 @@ dump_table(struct flow_table *ft) char action, flag_string[sizeof(fe->fe_flags) * 8 + 32]; unsigned int need_drop_reason = 0; const char *drop_reason = NULL; - struct in_addr in_src, in_dest; + char in_src[64], in_dest[64]; printf("Flow table\n\n"); dump_legend(); @@ -156,9 +156,11 @@ dump_table(struct flow_table *ft) need_drop_reason = 0; fe = (struct vr_flow_entry *)((char *)ft->ft_entries + (i * sizeof(*fe))); if (fe->fe_flags & VR_FLOW_FLAG_ACTIVE) { - if (fe->fe_type == VP_TYPE_IP) { - in_src.s_addr = fe->fe_key.flow4_sip; - in_dest.s_addr = fe->fe_key.flow4_dip; + if ((fe->fe_type == VP_TYPE_IP) || (fe->fe_type == VP_TYPE_IP6)) { + inet_ntop(VR_FLOW_FAMILY(fe->fe_type), fe->fe_key.flow_ip, in_src, 64); + inet_ntop(VR_FLOW_FAMILY(fe->fe_type), + &fe->fe_key.flow_ip[VR_FLOW_IP_ADDR_SIZE(fe->fe_type)], + in_dest, 64); } printf("%6d", i); @@ -167,14 +169,10 @@ dump_table(struct flow_table *ft) else printf(" "); - if (fe->fe_type == VP_TYPE_IP) { - printf(" %12s:%-5d ", inet_ntoa(in_src), - ntohs(fe->fe_key.flow4_sport)); - printf("%16s:%-5d %d (%d", - inet_ntoa(in_dest), - ntohs(fe->fe_key.flow4_dport), - fe->fe_key.flow4_proto, - fe->fe_vrf); + if ((fe->fe_type == VP_TYPE_IP) || (fe->fe_type == VP_TYPE_IP6)) { + printf(" %24s:%-5d ", in_src, ntohs(fe->fe_key.flow_sport)); + printf("%24s:%-5d %d (%d", in_dest, ntohs(fe->fe_key.flow_dport), + fe->fe_key.flow_proto, fe->fe_vrf); } if (fe->fe_flags & VR_FLOW_FLAG_VRFT) @@ -229,8 +227,8 @@ dump_table(struct flow_table *ft) } printf("\t("); - if (fe->fe_type == VP_TYPE_IP) - printf("K(nh):%u, ", fe->fe_key.flow4_nh_id); + if ((fe->fe_type == VP_TYPE_IP) || (fe->fe_type == VP_TYPE_IP6)) + printf("K(nh):%u, ", fe->fe_key.flow_nh_id); printf("Action:%c", action); if (need_flag_print) @@ -606,18 +604,20 @@ flow_validate(int flow_index, char action) memset(&flow_req, 0, sizeof(flow_req)); fe = flow_get(flow_index); - if (fe->fe_type != VP_TYPE_IP) + if ((fe->fe_type != VP_TYPE_IP) && (fe->fe_type != VP_TYPE_IP6)) return; flow_req.fr_op = FLOW_OP_FLOW_SET; flow_req.fr_index = flow_index; + flow_req.fr_family = VR_FLOW_FAMILY(fe->fe_type); flow_req.fr_flags = VR_FLOW_FLAG_ACTIVE; - flow_req.fr_flow_sip = fe->fe_key.flow4_sip; - flow_req.fr_flow_dip = fe->fe_key.flow4_dip; - flow_req.fr_flow_proto = fe->fe_key.flow4_proto; - flow_req.fr_flow_sport = fe->fe_key.flow4_sport; - flow_req.fr_flow_dport = fe->fe_key.flow4_dport; - flow_req.fr_flow_nh_id = fe->fe_key.flow4_nh_id; + memcpy(flow_req.fr_flow_ip, fe->fe_key.flow_ip, + 2*VR_FLOW_IP_ADDR_SIZE(fe->fe_type)); + flow_req.fr_flow_ip_size = 2*VR_FLOW_IP_ADDR_SIZE(fe->fe_type); + flow_req.fr_flow_proto = fe->fe_key.flow_proto; + flow_req.fr_flow_sport = fe->fe_key.flow_sport; + flow_req.fr_flow_dport = fe->fe_key.flow_dport; + flow_req.fr_flow_nh_id = fe->fe_key.flow_nh_id; switch (action) { case 'd':