Skip to content

Commit

Permalink
gt: support a single gateway for non-local traffic
Browse files Browse the repository at this point in the history
This patch allows Grantor servers to support a single gateway
for non-local traffic and still avoid having an LPM lookup.

It also demonstrates the network configurations
for a deployment scenario, as described in AltraMayor#267 and AltraMayor#417.
  • Loading branch information
mengxiang0811 committed Jul 26, 2020
1 parent 1c0161f commit ffdef52
Showing 1 changed file with 57 additions and 39 deletions.
96 changes: 57 additions & 39 deletions gt/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -535,46 +535,10 @@ gt_neigh_get_ether_cache(struct neighbor_hash_table *neigh,
uint16_t inner_ip_ver, void *ip_dst, struct gatekeeper_if *iface)
{
int ret;
char ip[128];
struct ether_cache *eth_cache = lookup_ether_cache(neigh, ip_dst);
if (eth_cache != NULL)
return eth_cache;

if (inner_ip_ver == RTE_ETHER_TYPE_IPV4) {
if (!ip4_same_subnet(iface->ip4_addr.s_addr,
*(uint32_t *)ip_dst, iface->ip4_mask.s_addr)) {
if (inet_ntop(AF_INET, ip_dst,
ip, sizeof(ip)) == NULL) {
GT_LOG(ERR,
"%s: failed to convert a number to an IPv4 address (%s)\n",
__func__, strerror(errno));
return NULL;
}

GT_LOG(WARNING,
"%s: receiving an IPv4 packet with destination IP address %s, which is not on the same subnet as the GT server\n",
__func__, ip);
return NULL;
}
} else if (likely(inner_ip_ver == RTE_ETHER_TYPE_IPV6)) {
if (!ip6_same_subnet(&iface->ip6_addr, ip_dst,
&iface->ip6_mask)) {
if (inet_ntop(AF_INET6, ip_dst,
ip, sizeof(ip)) == NULL) {
GT_LOG(ERR,
"%s: failed to convert a number to an IPv6 address (%s)\n",
__func__, strerror(errno));
return NULL;
}

GT_LOG(WARNING,
"%s: receiving an IPv6 packet with destination IP address %s, which is not on the same subnet as the GT server\n",
__func__, ip);
return NULL;
}
} else
return NULL;

eth_cache = get_new_ether_cache(neigh);
if (eth_cache == NULL) {
ret = drop_cache_entry_randomly(neigh, inner_ip_ver);
Expand Down Expand Up @@ -620,9 +584,13 @@ static int
decap_and_fill_eth(struct rte_mbuf *m, struct gt_config *gt_conf,
struct gt_packet_headers *pkt_info, struct gt_instance *instance)
{
struct neighbor_hash_table *neigh;
char ip[128];
struct neighbor_hash_table *neigh = NULL;
struct ether_cache *eth_cache;
void *ip_dst;
bool is_not_neighbor = false;
struct rte_ether_hdr eth_hdr_tmp;
struct rte_ether_hdr *raw_eth;
int bytes_to_add;

if (pkt_info->inner_ip_ver == RTE_ETHER_TYPE_IPV4) {
Expand All @@ -643,8 +611,24 @@ decap_and_fill_eth(struct rte_mbuf *m, struct gt_config *gt_conf,
set_ipv4_checksum(&gt_conf->net->front, m, inner_ipv4_hdr);
}

neigh = &instance->neigh;
ip_dst = &inner_ipv4_hdr->dst_addr;

if (!ip4_same_subnet(iface->ip4_addr.s_addr,
*(uint32_t *)ip_dst, iface->ip4_mask.s_addr)) {
if (inet_ntop(AF_INET, ip_dst,
ip, sizeof(ip)) == NULL) {
GT_LOG(ERR,
"%s: failed to convert a number to an IPv4 address (%s)\n",
__func__, strerror(errno));
return -1;
}

is_not_neighbor = true;
raw_eth = (struct rte_ether_hdr *)pkt_info->l2_hdr;
rte_ether_addr_copy(&raw_eth->s_addr, &eth_hdr_tmp.d_addr);
rte_ether_addr_copy(&raw_eth->d_addr, &eth_hdr_tmp.s_addr);
} else
neigh = &instance->neigh;
} else if (likely(pkt_info->inner_ip_ver == RTE_ETHER_TYPE_IPV6)) {
/*
* Since there's no checksum in the IPv6 header, skip the
Expand All @@ -656,8 +640,24 @@ decap_and_fill_eth(struct rte_mbuf *m, struct gt_config *gt_conf,
inner_ipv6_hdr->vtc_flow |=
rte_cpu_to_be_32(IPTOS_ECN_CE << 20);

neigh = &instance->neigh6;
ip_dst = inner_ipv6_hdr->dst_addr;

if (!ip6_same_subnet(&iface->ip6_addr, ip_dst,
&iface->ip6_mask)) {
if (inet_ntop(AF_INET6, ip_dst,
ip, sizeof(ip)) == NULL) {
GT_LOG(ERR,
"%s: failed to convert a number to an IPv6 address (%s)\n",
__func__, strerror(errno));
return -1;
}

is_not_neighbor = true;
raw_eth = (struct rte_ether_hdr *)pkt_info->l2_hdr;
rte_ether_addr_copy(&raw_eth->s_addr, &eth_hdr_tmp.d_addr);
rte_ether_addr_copy(&raw_eth->d_addr, &eth_hdr_tmp.s_addr);
} else
neigh = &instance->neigh6;
} else
return -1;

Expand All @@ -671,6 +671,24 @@ decap_and_fill_eth(struct rte_mbuf *m, struct gt_config *gt_conf,
return -1;
}

if (is_not_neighbor) {
struct rte_ether_hdr *eth_hdr =
rte_pktmbuf_mtod(m, struct rte_ether_hdr *);

rte_memcpy(eth_hdr, &eth_hdr_tmp, gt_conf->net->front.l2_len_out);
m->l2_len = gt_conf->net->front.l2_len_out;

if (iface->vlan_insert) {
fill_vlan_hdr(eth_hdr, iface->vlan_tag_be,
pkt_info->outer_ethertype);
} else {
eth_hdr->ether_type =
rte_cpu_to_be_16(pkt_info->outer_ethertype);
}

return 0;
}

/*
* The destination MAC address comes from LLS block.
*/
Expand Down

0 comments on commit ffdef52

Please sign in to comment.