Skip to content

Commit

Permalink
Merge "Respond with stitched MAC for unicast ARP request" into R3.0
Browse files Browse the repository at this point in the history
  • Loading branch information
Zuul authored and opencontrail-ci-admin committed Sep 2, 2016
2 parents 93ec459 + 7cc0122 commit 54f87b0
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 29 deletions.
73 changes: 58 additions & 15 deletions dp-core/vr_datapath.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,15 @@ vr_get_proxy_mac(struct vr_packet *pkt, struct vr_forwarding_md *fmd,
struct vr_route_req *rt, unsigned char *dmac)
{
bool from_fabric, stitched, flood;
bool to_gateway, no_proxy, to_vcp;
bool to_gateway, no_proxy, to_vcp, ecmp_src;

unsigned char *resp_mac;
struct vr_nexthop *nh = NULL;
struct vr_interface *vif = pkt->vp_if;
struct vr_vrf_stats *stats;

from_fabric = stitched = flood = to_gateway = to_vcp = no_proxy = false;
from_fabric = stitched = flood = false;
to_gateway = to_vcp = no_proxy = ecmp_src = false;

stats = vr_inet_vrf_stats(fmd->fmd_dvrf, pkt->vp_cpu);
/* here we will not check for stats, but will check before use */
Expand Down Expand Up @@ -65,11 +66,12 @@ vr_get_proxy_mac(struct vr_packet *pkt, struct vr_forwarding_md *fmd,
}
}

/* If ECMP source, we force routing */
if (fmd->fmd_ecmp_src_nh_index != -1) {
resp_mac = vif->vif_mac;
fmd->fmd_ecmp_src_nh_index = -1;
}
/* If ECMP source, we force routing */
if (fmd->fmd_ecmp_src_nh_index != -1) {
resp_mac = vif->vif_mac;
fmd->fmd_ecmp_src_nh_index = -1;
ecmp_src = true;
}


/*
Expand All @@ -87,6 +89,38 @@ vr_get_proxy_mac(struct vr_packet *pkt, struct vr_forwarding_md *fmd,
* . arp request from the uplink port of a vcp
*/
if (from_fabric) {
if (ecmp_src) {

/*
* If a Multicast ARP request, it is not answered on Fabric
* side
*/
if (IS_MAC_BMCAST(dmac))
return MR_DROP;

/*
* If unicast and not stiched, we do not have enough
* information what to respond. We can not even flood,
* probably because this need to be answered with Vrouter
* Mac in source Vrouter itself. So we drop this
*/
if (!stitched)
return MR_DROP;

/*
* If our stiched mac does not match, we will let the VM
* decide what to do with request
*/
if (!VR_MAC_CMP(dmac, rt->rtr_req.rtr_mac))
return MR_FLOOD;

/*
* Very likely response need to go with stiched mac. But
* below conditions might override
*/
resp_mac = rt->rtr_req.rtr_mac;
}

if (flood && !stitched) {
if (stats)
stats->vrf_arp_physical_flood++;
Expand Down Expand Up @@ -229,14 +263,15 @@ vr_arp_proxy(struct vr_arp *sarp, struct vr_packet *pkt,

static int
vr_handle_arp_request(struct vr_arp *sarp, struct vr_packet *pkt,
struct vr_forwarding_md *fmd)
struct vr_forwarding_md *fmd, unsigned char *eth_dmac)
{
bool handled = true;
unsigned char dmac[VR_ETHER_ALEN];
mac_response_t arp_result;

struct vr_packet *pkt_c;
struct vr_interface *vif = pkt->vp_if;
VR_MAC_COPY(dmac, eth_dmac);

arp_result = vif->vif_mac_request(vif, pkt, fmd, dmac);
switch (arp_result) {
Expand Down Expand Up @@ -386,6 +421,7 @@ vif_plug_mac_request(struct vr_interface *vif, struct vr_packet *pkt,
struct vr_forwarding_md *fmd)
{
int nheader, handled = 1;
unsigned char eth_dmac[VR_ETHER_ALEN];

if (pkt->vp_flags & VP_FLAG_MULTICAST)
goto unhandled;
Expand All @@ -394,13 +430,15 @@ vif_plug_mac_request(struct vr_interface *vif, struct vr_packet *pkt,
if (nheader < 0 || (pkt->vp_data + nheader > pkt->vp_end))
goto unhandled;

VR_MAC_COPY(eth_dmac, pkt_data(pkt));

if (pkt->vp_type == VP_TYPE_ARP) {
if (pkt->vp_len < (nheader + sizeof(struct vr_arp)))
goto unhandled;

pkt_pull(pkt, nheader);

handled = vr_arp_input(pkt, fmd);
handled = vr_arp_input(pkt, fmd, eth_dmac);
if (!handled) {
pkt_push(pkt, nheader);
}
Expand All @@ -413,7 +451,7 @@ vif_plug_mac_request(struct vr_interface *vif, struct vr_packet *pkt,

pkt_pull(pkt, nheader);

handled = vr_neighbor_input(pkt, fmd);
handled = vr_neighbor_input(pkt, fmd, eth_dmac);
if (!handled) {
pkt_push(pkt, nheader);
}
Expand Down Expand Up @@ -468,7 +506,8 @@ vr_pkt_type(struct vr_packet *pkt, unsigned short offset,
}

int
vr_arp_input(struct vr_packet *pkt, struct vr_forwarding_md *fmd)
vr_arp_input(struct vr_packet *pkt, struct vr_forwarding_md *fmd,
unsigned char *eth_dmac)
{
int handled = 1;
struct vr_arp sarp;
Expand All @@ -486,7 +525,7 @@ vr_arp_input(struct vr_packet *pkt, struct vr_forwarding_md *fmd)

switch (ntohs(sarp.arp_op)) {
case VR_ARP_OP_REQUEST:
return vr_handle_arp_request(&sarp, pkt, fmd);
return vr_handle_arp_request(&sarp, pkt, fmd, eth_dmac);

case VR_ARP_OP_REPLY:
return vr_handle_arp_reply(&sarp, pkt, fmd);
Expand Down Expand Up @@ -600,6 +639,7 @@ vr_fabric_input(struct vr_interface *vif, struct vr_packet *pkt,
int handled = 0;
unsigned short pull_len;
struct vr_forwarding_md fmd;
unsigned char *data, eth_dmac[VR_ETHER_ALEN];

vr_init_forwarding_md(&fmd);
fmd.fmd_vlan = vlan_id;
Expand All @@ -622,13 +662,16 @@ vr_fabric_input(struct vr_interface *vif, struct vr_packet *pkt,
return vif_xconnect(vif, pkt, &fmd);
}

data = pkt_data(pkt);
pull_len = pkt_get_network_header_off(pkt) - pkt_head_space(pkt);
pkt_pull(pkt, pull_len);

if (pkt->vp_type == VP_TYPE_IP || pkt->vp_type == VP_TYPE_IP6)
if (pkt->vp_type == VP_TYPE_IP || pkt->vp_type == VP_TYPE_IP6) {
handled = vr_l3_input(pkt, &fmd);
else if (pkt->vp_type == VP_TYPE_ARP)
handled = vr_arp_input(pkt, &fmd);
} else if (pkt->vp_type == VP_TYPE_ARP) {
VR_MAC_COPY(eth_dmac, data);
handled = vr_arp_input(pkt, &fmd, eth_dmac);
}

if (!handled) {
pkt_push(pkt, pull_len);
Expand Down
26 changes: 15 additions & 11 deletions dp-core/vr_nexthop.c
Original file line number Diff line number Diff line change
Expand Up @@ -274,13 +274,15 @@ static int
nh_l2_rcv(struct vr_packet *pkt, struct vr_nexthop *nh,
struct vr_forwarding_md *fmd)
{
struct vr_vrf_stats *stats;
unsigned char eth_dmac[VR_ETHER_ALEN], *data;
int pull_len, handled = 0;
struct vr_vrf_stats *stats;

stats = vr_inet_vrf_stats(fmd->fmd_dvrf, pkt->vp_cpu);
if (stats)
stats->vrf_l2_receives++;

data = pkt_data(pkt);
fmd->fmd_to_me = 1;
pull_len = pkt_get_network_header_off(pkt) - pkt_head_space(pkt);
if (pkt_pull(pkt, pull_len) < 0) {
Expand All @@ -294,13 +296,15 @@ nh_l2_rcv(struct vr_packet *pkt, struct vr_nexthop *nh,
* generated by Agent for some features
*/
if (pkt->vp_type == VP_TYPE_IP6) {
handled = vr_neighbor_input(pkt, fmd);
VR_MAC_COPY(eth_dmac, data);
handled = vr_neighbor_input(pkt, fmd, eth_dmac);
if (!handled)
handled = vr_l3_input(pkt, fmd);
} else if (pkt->vp_type == VP_TYPE_IP) {
handled = vr_l3_input(pkt, fmd);
} else if (pkt->vp_type == VP_TYPE_ARP) {
handled = vr_arp_input(pkt, fmd);
VR_MAC_COPY(eth_dmac, data);
handled = vr_arp_input(pkt, fmd, eth_dmac);
}

if (!handled)
Expand Down Expand Up @@ -690,13 +694,13 @@ nh_composite_mcast_validate_src(struct vr_packet *pkt, struct vr_nexthop *nh,
}

static int
nh_handle_mcast_control_pkt(struct vr_packet *pkt, struct vr_forwarding_md *fmd,
unsigned int pkt_src, bool *flood_to_vms)
nh_handle_mcast_control_pkt(struct vr_packet *pkt, struct vr_eth *eth,
struct vr_forwarding_md *fmd, unsigned int pkt_src, bool *flood_to_vms)
{
int handled = 1;
unsigned char eth_dmac[VR_ETHER_ALEN];
unsigned short trap, rt_flags, drop_reason, pull_len = 0;
l4_pkt_type_t l4_type = L4_TYPE_UNKNOWN;
struct vr_eth *eth;
struct vr_arp *sarp;
struct vr_nexthop *src_nh;
struct vr_ip6 *ip6;
Expand All @@ -707,16 +711,15 @@ nh_handle_mcast_control_pkt(struct vr_packet *pkt, struct vr_forwarding_md *fmd,
if (fmd->fmd_vlan != VLAN_ID_INVALID)
return !handled;

eth = (struct vr_eth *)pkt_data(pkt);

pull_len = pkt_get_network_header_off(pkt) - pkt_head_space(pkt);
if (pkt_pull(pkt, pull_len) < 0) {
drop_reason = VP_DROP_PULL;
goto drop;
}

if (pkt->vp_type == VP_TYPE_ARP) {
handled = vr_arp_input(pkt, fmd);
VR_MAC_COPY(eth_dmac, eth->eth_dmac);
handled = vr_arp_input(pkt, fmd, eth_dmac);
if (handled)
return handled;

Expand Down Expand Up @@ -781,7 +784,8 @@ nh_handle_mcast_control_pkt(struct vr_packet *pkt, struct vr_forwarding_md *fmd,
}

if (l4_type == L4_TYPE_NEIGHBOUR_SOLICITATION) {
handled = vr_neighbor_input(pkt, fmd);
VR_MAC_COPY(eth_dmac, eth->eth_dmac);
handled = vr_neighbor_input(pkt, fmd, eth_dmac);
if (handled)
return handled;

Expand Down Expand Up @@ -867,7 +871,7 @@ nh_composite_mcast_l2(struct vr_packet *pkt, struct vr_nexthop *nh,
goto drop;
}

handled = nh_handle_mcast_control_pkt(pkt, fmd, pkt_src, &flood_to_vms);
handled = nh_handle_mcast_control_pkt(pkt, eth, fmd, pkt_src, &flood_to_vms);
if (handled)
return 0;

Expand Down
5 changes: 4 additions & 1 deletion dp-core/vr_proto_ip6.c
Original file line number Diff line number Diff line change
Expand Up @@ -404,7 +404,8 @@ vm_neighbor_request(struct vr_interface *vif, struct vr_packet *pkt,
}

int
vr_neighbor_input(struct vr_packet *pkt, struct vr_forwarding_md *fmd)
vr_neighbor_input(struct vr_packet *pkt, struct vr_forwarding_md *fmd,
unsigned char *eth_dmac)
{
int handled = 1;
uint32_t pull_len, len;
Expand Down Expand Up @@ -453,6 +454,8 @@ vr_neighbor_input(struct vr_packet *pkt, struct vr_forwarding_md *fmd)
if (nopt->vno_type != SOURCE_LINK_LAYER_ADDRESS_OPTION)
goto drop;

VR_MAC_COPY(dmac, eth_dmac);

ndisc_result = vif->vif_mac_request(vif, pkt, fmd, dmac);
switch (ndisc_result) {
case MR_PROXY:
Expand Down
5 changes: 3 additions & 2 deletions include/vr_datapath.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,11 @@ unsigned int vr_fabric_input(struct vr_interface *, struct vr_packet *,

int vr_l3_input(struct vr_packet *, struct vr_forwarding_md *);
int vr_l2_input(struct vr_packet *, struct vr_forwarding_md *);
int vr_arp_input(struct vr_packet *, struct vr_forwarding_md *);
int vr_arp_input(struct vr_packet *, struct vr_forwarding_md *, unsigned char *);
int vr_ip_input(struct vrouter *, struct vr_packet *,
struct vr_forwarding_md *);
int vr_neighbor_input(struct vr_packet *, struct vr_forwarding_md *);
int vr_neighbor_input(struct vr_packet *, struct vr_forwarding_md *,
unsigned char *);
int vr_ip6_input(struct vrouter *, struct vr_packet *,
struct vr_forwarding_md *);
extern void vr_ip_update_csum(struct vr_packet *, unsigned int, unsigned int);
Expand Down

0 comments on commit 54f87b0

Please sign in to comment.