Skip to content

Commit

Permalink
Merge "Do a route table lookup post vrf translation" into R2.1
Browse files Browse the repository at this point in the history
  • Loading branch information
Zuul authored and opencontrail-ci-admin committed Mar 27, 2015
2 parents 88af46c + de2da47 commit b90b14a
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 39 deletions.
9 changes: 8 additions & 1 deletion dp-core/vr_datapath.c
Original file line number Diff line number Diff line change
Expand Up @@ -452,8 +452,15 @@ vr_reinject_packet(struct vr_packet *pkt, struct vr_forwarding_md *fmd)
struct vr_interface *vif = pkt->vp_if;
int handled;

if (pkt->vp_nh)
if (pkt->vp_nh) {
/* If nexthop does not have valid data, drop it */
if (!(pkt->vp_nh->nh_flags & NH_FLAG_VALID)) {
vr_pfree(pkt, VP_DROP_INVALID_NH);
return 0;
}

return pkt->vp_nh->nh_reach_nh(pkt, pkt->vp_nh, fmd);
}

if (vif_is_vhost(vif)) {
handled = vr_l3_input(pkt, fmd);
Expand Down
27 changes: 18 additions & 9 deletions dp-core/vr_nexthop.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,10 @@
extern bool vr_has_to_fragment(struct vr_interface *, struct vr_packet *,
unsigned int);
extern struct vr_vrf_stats *(*vr_inet_vrf_stats)(unsigned short, unsigned int);
extern struct vr_nexthop *vr_inet6_sip_lookup(unsigned short, uint8_t *);
extern struct vr_nexthop *vr_inet_sip_lookup(unsigned short, uint32_t);
extern struct vr_nexthop *vr_inet_src_lookup(unsigned short ,
struct vr_ip *, struct vr_packet *);
extern struct vr_nexthop *vr_inet6_ip_lookup(unsigned short, uint8_t *);
extern struct vr_nexthop *vr_inet_ip_lookup(unsigned short, uint32_t);
extern struct vr_nexthop *vr_inet_src_lookup(unsigned short,
struct vr_packet *);
extern l4_pkt_type_t vr_ip6_well_known_packet(struct vr_packet *);
extern l4_pkt_type_t vr_ip_well_known_packet(struct vr_packet *);

Expand Down Expand Up @@ -663,7 +663,7 @@ nh_composite_mcast_l2(struct vr_packet *pkt, struct vr_nexthop *nh,

if (pkt_src) {
sarp = (struct vr_arp *)pkt_data(pkt);
src_nh = vr_inet_sip_lookup(fmd->fmd_dvrf, sarp->arp_spa);
src_nh = vr_inet_ip_lookup(fmd->fmd_dvrf, sarp->arp_spa);
if (vr_gateway_nexthop(src_nh))
flood_to_vms = false;
}
Expand Down Expand Up @@ -716,7 +716,7 @@ nh_composite_mcast_l2(struct vr_packet *pkt, struct vr_nexthop *nh,

if (pkt_src) {
ip6 = (struct vr_ip6 *)pkt_data(pkt);
src_nh = vr_inet6_sip_lookup(fmd->fmd_dvrf, ip6->ip6_src);
src_nh = vr_inet6_ip_lookup(fmd->fmd_dvrf, ip6->ip6_src);
if (vr_gateway_nexthop(src_nh))
flood_to_vms = false;
}
Expand Down Expand Up @@ -1608,7 +1608,6 @@ nh_output(struct vr_packet *pkt, struct vr_nexthop *nh,
struct vr_forwarding_md *fmd)
{
struct vr_nexthop *src_nh = NULL;
struct vr_ip *ip;
bool need_flow_lookup = false;

if (!pkt->vp_ttl) {
Expand Down Expand Up @@ -1638,26 +1637,36 @@ nh_output(struct vr_packet *pkt, struct vr_nexthop *nh,
* Typical example for this situation is when the packet reaches the
* target VM's server from an ECMP-ed service chain.
*/
ip = (struct vr_ip *)pkt_network_header(pkt);
if (!(pkt->vp_flags & VP_FLAG_FLOW_SET)) {
if (nh->nh_flags & NH_FLAG_POLICY_ENABLED) {
need_flow_lookup = true;
} else {
src_nh = vr_inet_src_lookup(fmd->fmd_dvrf, ip, pkt);
src_nh = vr_inet_src_lookup(fmd->fmd_dvrf, pkt);
if (src_nh && src_nh->nh_type == NH_COMPOSITE &&
src_nh->nh_flags & NH_FLAG_COMPOSITE_ECMP) {
need_flow_lookup = true;
}
}

if (need_flow_lookup) {
pkt->vp_flags |= VP_FLAG_FLOW_GET;
/*
* after vr_flow_forward returns, pkt->vp_nh could have changed
* since in NAT cases the new destination should have been
* looked up.
*/
if (!vr_flow_forward(nh->nh_router, pkt, fmd))
return 0;

/* pkt->vp_nh could have changed after vr_flow_forward */
if (!pkt->vp_nh) {
vr_pfree(pkt, VP_DROP_INVALID_NH);
return 0;
}

if (nh != pkt->vp_nh) {
return nh_output(pkt, pkt->vp_nh, fmd);
}
}
}
}
Expand Down
49 changes: 20 additions & 29 deletions dp-core/vr_proto_ip.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,9 @@
#include "vr_bridge.h"

static unsigned short vr_ip_id;
extern struct vr_vrf_stats *(*vr_inet_vrf_stats)(unsigned short,
unsigned int);

extern struct vr_vrf_stats *(*vr_inet_vrf_stats)(unsigned short, unsigned int);
extern struct vr_nexthop *vr_inet6_ip_lookup(unsigned short, uint8_t *);

unsigned short
vr_generate_unique_ip_id()
Expand All @@ -30,34 +31,15 @@ vr_generate_unique_ip_id()
}

struct vr_nexthop *
vr_inet6_sip_lookup(unsigned short vrf, uint8_t *sip6)
{
uint32_t rt_prefix[4];

struct vr_route_req rt;

rt.rtr_req.rtr_vrf_id = vrf;
rt.rtr_req.rtr_prefix = (uint8_t*)&rt_prefix;
memcpy(rt.rtr_req.rtr_prefix, sip6, 16);
rt.rtr_req.rtr_prefix_size = 16;
rt.rtr_req.rtr_prefix_len = IP6_PREFIX_LEN;
rt.rtr_req.rtr_family = AF_INET6;
rt.rtr_req.rtr_marker_size = 0;
rt.rtr_req.rtr_nh_id = 0;

return vr_inet_route_lookup(vrf, &rt);
}

struct vr_nexthop *
vr_inet_sip_lookup(unsigned short vrf, uint32_t sip)
vr_inet_ip_lookup(unsigned short vrf, uint32_t ip)
{
uint32_t rt_prefix;

struct vr_route_req rt;

rt.rtr_req.rtr_vrf_id = vrf;
rt.rtr_req.rtr_prefix = (uint8_t *)&rt_prefix;
*(uint32_t*)rt.rtr_req.rtr_prefix = sip;
*(uint32_t*)rt.rtr_req.rtr_prefix = ip;
rt.rtr_req.rtr_prefix_size = 4;
rt.rtr_req.rtr_prefix_len = IP4_PREFIX_LEN;
rt.rtr_req.rtr_family = AF_INET;
Expand All @@ -68,18 +50,26 @@ vr_inet_sip_lookup(unsigned short vrf, uint32_t sip)
}

struct vr_nexthop *
vr_inet_src_lookup(unsigned short vrf, struct vr_ip *ip, struct vr_packet *pkt)
vr_inet_src_lookup(unsigned short vrf, struct vr_packet *pkt)
{
struct vr_ip *ip;
struct vr_ip6 *ip6;

if (!ip || !pkt)
if (!pkt)
return NULL;

if (pkt->vp_type == VP_TYPE_IP) {
return vr_inet_sip_lookup(vrf, ip->ip_saddr);
ip = (struct vr_ip *)pkt_network_header(pkt);
if (!ip)
return NULL;

return vr_inet_ip_lookup(vrf, ip->ip_saddr);
} else if (pkt->vp_type == VP_TYPE_IP6) {
ip6 = (struct vr_ip6 *)pkt_data(pkt);
return vr_inet6_sip_lookup(vrf, ip6->ip6_src);
ip6 = (struct vr_ip6 *)pkt_network_header(pkt);
if (!ip6)
return NULL;

return vr_inet6_ip_lookup(vrf, ip6->ip6_src);
}

return NULL;
Expand Down Expand Up @@ -745,7 +735,8 @@ vr_inet_flow_nat(struct vr_flow_entry *fe, struct vr_packet *pkt,

if ((fe->fe_flags & VR_FLOW_FLAG_VRFT) &&
pkt->vp_nh && pkt->vp_nh->nh_vrf != fmd->fmd_dvrf) {
pkt->vp_nh = NULL;
/* only if pkt->vp_nh was set before... */
pkt->vp_nh = vr_inet_ip_lookup(fmd->fmd_dvrf, ip->ip_daddr);
}

return FLOW_FORWARD;
Expand Down
19 changes: 19 additions & 0 deletions dp-core/vr_proto_ip6.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,25 @@
#include <vr_ip_mtrie.h>
#include <vr_bridge.h>

struct vr_nexthop *
vr_inet6_ip_lookup(unsigned short vrf, uint8_t *ip6)
{
uint32_t rt_prefix[4];

struct vr_route_req rt;

rt.rtr_req.rtr_vrf_id = vrf;
rt.rtr_req.rtr_prefix = (uint8_t*)&rt_prefix;
memcpy(rt.rtr_req.rtr_prefix, ip6, 16);
rt.rtr_req.rtr_prefix_size = 16;
rt.rtr_req.rtr_prefix_len = IP6_PREFIX_LEN;
rt.rtr_req.rtr_family = AF_INET6;
rt.rtr_req.rtr_marker_size = 0;
rt.rtr_req.rtr_nh_id = 0;

return vr_inet_route_lookup(vrf, &rt);
}

static int
vr_v6_prefix_is_ll(uint8_t prefix[])
{
Expand Down

0 comments on commit b90b14a

Please sign in to comment.