Skip to content

Commit

Permalink
Flooding of Unknown unicast Frames
Browse files Browse the repository at this point in the history
The L2 bridge miss packets are dropped as of now. This leads
to network disconnectivity if BM ARP timeout is longer than Bridge
timeout. To avoid this, unknow unicast packets are flooded
into multicast tree. This flooding is limited by per VN flag
for user. For Vrouter, the per VN flag is trnanslated to VIF
and VrfTranslate NH. If unicast lookup fails, and if the above
flag is set, packet if forwarded to broadcast tree. A counter is also
added when unknown unicast is flooded.

Change-Id: Ia618f6fa981e13b0163e0cd5cb3bdb0919fad901
partial-bug:#1424523
  • Loading branch information
divakardhar committed Apr 28, 2015
1 parent 70562f4 commit 7ff3bce
Show file tree
Hide file tree
Showing 9 changed files with 58 additions and 5 deletions.
41 changes: 39 additions & 2 deletions dp-core/vr_bridge.c
Expand Up @@ -49,6 +49,7 @@ int bridge_table_init(struct vr_rtable *, struct rtable_fspec *);
void bridge_table_deinit(struct vr_rtable *, struct rtable_fspec *, bool);
struct vr_bridge_entry *vr_find_bridge_entry(struct vr_bridge_entry_key *);
struct vr_bridge_entry *vr_find_free_bridge_entry(unsigned int, char *);
extern struct vr_vrf_stats *(*vr_inet_vrf_stats)(unsigned short, unsigned int);


static bool
Expand All @@ -65,6 +66,23 @@ bridge_entry_valid(vr_htable_t htable, vr_hentry_t hentry,
return false;
}


bool
vr_unknown_uc_flood(struct vr_interface *ingress_vif,
struct vr_nexthop *ingress_nh)
{
if (!ingress_vif)
return false;

if (vif_is_virtual(ingress_vif)) {
return ((ingress_vif->vif_flags & VIF_FLAG_UNKNOWN_UC_FLOOD) != 0);
} else if (vif_is_fabric(ingress_vif) && ingress_nh) {
return ((ingress_nh->nh_flags & NH_FLAG_UNKNOWN_UC_FLOOD) != 0);
}

return false;
}

struct vr_bridge_entry *
vr_find_bridge_entry(struct vr_bridge_entry_key *key)
{
Expand Down Expand Up @@ -420,6 +438,7 @@ vr_bridge_input(struct vrouter *router, struct vr_packet *pkt,
struct vr_nexthop *nh = NULL;
unsigned short pull_len, overlay_len = VROUTER_OVERLAY_LEN;
int reason, handled;
struct vr_vrf_stats *stats;

/* Do the bridge lookup for the packets not meant for "me" */
if (!fmd->fmd_to_me) {
Expand All @@ -434,8 +453,26 @@ vr_bridge_input(struct vrouter *router, struct vr_packet *pkt,

nh = vr_bridge_lookup(fmd->fmd_dvrf, &rt);
if (!nh) {
vr_pfree(pkt, VP_DROP_L2_NO_ROUTE);
return 0;

/* If Flooding of unknown unicast not allowed, drop the packet */
if (!vr_unknown_uc_flood(pkt->vp_if, pkt->vp_nh) ||
IS_MAC_BMCAST(rt.rtr_req.rtr_mac)) {
vr_pfree(pkt, VP_DROP_L2_NO_ROUTE);
return 0;
}

rt.rtr_req.rtr_mac = (int8_t *)vr_bcast_mac;
nh = vr_bridge_lookup(fmd->fmd_dvrf, &rt);
if (!nh) {
vr_pfree(pkt, VP_DROP_L2_NO_ROUTE);
return 0;
}
stats = vr_inet_vrf_stats(fmd->fmd_dvrf, pkt->vp_cpu);
if (stats)
stats->vrf_uuc_floods++;

/* Treat this unknown unicast packet as multicast */
pkt->vp_flags |= VP_FLAG_MULTICAST;
}

if (nh->nh_type != NH_L2_RCV)
Expand Down
1 change: 1 addition & 0 deletions dp-core/vr_ip_mtrie.c
Expand Up @@ -762,6 +762,7 @@ mtrie_stats_get(vr_vrf_stats_req *req, vr_vrf_stats_req *response)
response->vsr_arp_tor_proxy += stats->vrf_arp_tor_proxy;
response->vsr_arp_physical_flood += stats->vrf_arp_physical_flood;
response->vsr_vrf_translates += stats->vrf_vrf_translates;
response->vsr_uuc_floods += stats->vrf_uuc_floods;
}
}

Expand Down
1 change: 1 addition & 0 deletions include/vr_interface.h
Expand Up @@ -76,6 +76,7 @@
* so we copy all the packets to another interface
*/
#define VIF_FLAG_MONITORED 0x8000
#define VIF_FLAG_UNKNOWN_UC_FLOOD 0x10000

#define vif_mode_xconnect(vif) (vif->vif_flags & VIF_FLAG_XCONNECT)
#define vif_dhcp_enabled(vif) (vif->vif_flags & VIF_FLAG_DHCP_ENABLED)
Expand Down
1 change: 1 addition & 0 deletions include/vr_nexthop.h
Expand Up @@ -54,6 +54,7 @@ enum nexthop_type {
#define NH_FLAG_COMPOSITE_TOR 0x04000
#define NH_FLAG_VNID 0x08000
#define NH_FLAG_ROUTE_LOOKUP 0x10000
#define NH_FLAG_UNKNOWN_UC_FLOOD 0x20000

#define NH_SOURCE_INVALID 0
#define NH_SOURCE_VALID 1
Expand Down
1 change: 1 addition & 0 deletions include/vr_route.h
Expand Up @@ -57,6 +57,7 @@ struct vr_vrf_stats {
uint64_t vrf_arp_physical_stitch;
uint64_t vrf_arp_tor_proxy;
uint64_t vrf_arp_physical_flood;
uint64_t vrf_uuc_floods;
};

struct vr_route {
Expand Down
1 change: 1 addition & 0 deletions sandesh/vr.sandesh
Expand Up @@ -199,6 +199,7 @@ buffer sandesh vr_vrf_stats_req {
28: i64 vsr_arp_tor_proxy;
29: i64 vsr_arp_physical_flood;
30: i64 vsr_l2_receives;
31: i64 vsr_uuc_floods;
}

buffer sandesh vr_response {
Expand Down
10 changes: 9 additions & 1 deletion utils/nh.c
Expand Up @@ -163,6 +163,9 @@ nh_flags(uint32_t flags, uint8_t type, char *ptr)
case NH_FLAG_VNID:
strcat(ptr, "Vxlan, ");
break;
case NH_FLAG_UNKNOWN_UC_FLOOD:
strcat(ptr, "Unicast Flood, ");
break;
}
}
return ptr;
Expand Down Expand Up @@ -445,7 +448,8 @@ cmd_usage()
" [--tor composit tor ]\n"
" [--lbl <lbl> label for composit fabric ]\n"
" [VRF Translate options]\n"
" [--vxlan Vxlan VRF Translation]\n");
" [--vxlan Vxlan VRF Translation]\n"
" [--uucf Unknown Unicast Flood]\n");
exit(-EINVAL);
}

Expand Down Expand Up @@ -486,6 +490,7 @@ enum opt_index {
TOR_OPT_IND,
RLKUP_OPT_IND,
LBL_OPT_IND,
UUCF_OPT_IND,
LST_OPT_IND,
GET_OPT_IND,
CRT_OPT_IND,
Expand Down Expand Up @@ -531,6 +536,7 @@ static struct option long_options[] = {
[TOR_OPT_IND] = {"tor", no_argument, &opt[TOR_OPT_IND], 1},
[RLKUP_OPT_IND] = {"rlkup", no_argument, &opt[RLKUP_OPT_IND], 1},
[LBL_OPT_IND] = {"lbl", required_argument, &opt[LBL_OPT_IND], 1},
[UUCF_OPT_IND] = {"uucf", no_argument, &opt[UUCF_OPT_IND], 1},
[LST_OPT_IND] = {"list", no_argument, &opt[LST_OPT_IND], 1},
[GET_OPT_IND] = {"get", required_argument, &opt[GET_OPT_IND], 1},
[CRT_OPT_IND] = {"create", required_argument, &opt[CRT_OPT_IND], 1},
Expand Down Expand Up @@ -721,6 +727,8 @@ validate_options()
} else if (type == NH_VRF_TRANSLATE) {
if (opt_set(VXLAN_OPT_IND))
flags |= NH_FLAG_VNID;
if (opt_set(UUCF_OPT_IND))
flags |= NH_FLAG_UNKNOWN_UC_FLOOD;
} else {
cmd_usage();
}
Expand Down
1 change: 1 addition & 0 deletions utils/vif.c
Expand Up @@ -96,6 +96,7 @@ static struct vr_util_flags flag_metadata[] = {
{VIF_FLAG_PMD, "Dpdk", "DPDK PMD Interface"},
{VIF_FLAG_FILTERING_OFFLOAD,"Rfl", "Receive Filtering Offload"},
{VIF_FLAG_MONITORED, "Mon", "Interface is Monitored"},
{VIF_FLAG_UNKNOWN_UC_FLOOD, "Uuf", "Unknown Unicast Flood"},
};

static char *
Expand Down
6 changes: 4 additions & 2 deletions utils/vrfstats.c
Expand Up @@ -58,9 +58,11 @@ vr_vrf_stats_req_process(void *s_req)
stats_req.vsr_marker = stats->vsr_vrf;
printf("Vrf: %d\n", stats->vsr_vrf);
printf("Discards %" PRIu64 ", Resolves %" PRIu64 ", Receives %"
PRIu64 ", L2 Receives %" PRIu64 ", Vrf Translates %" PRIu64 "\n",
PRIu64 ", L2 Receives %" PRIu64 ", Vrf Translates %" PRIu64
", Unknown Unicast Floods %" PRIu64 "\n",
stats->vsr_discards, stats->vsr_resolves, stats->vsr_receives,
stats->vsr_l2_receives, stats->vsr_vrf_translates);
stats->vsr_l2_receives, stats->vsr_vrf_translates,
stats->vsr_uuc_floods);
printf("Ecmp Composites %" PRIu64 ", L2 Mcast Composites %"
PRIu64 ", Fabric Composites %" PRIu64 ", Encap Composites %" PRIu64
", Evpn Composites %" PRIu64 "\n", stats->vsr_ecmp_composites,
Expand Down

0 comments on commit 7ff3bce

Please sign in to comment.