Skip to content

Commit

Permalink
Merge "In BGP service if VM sends TTL 1 session doesnt come up." into…
Browse files Browse the repository at this point in the history
… R3.1
  • Loading branch information
Zuul authored and opencontrail-ci-admin committed Aug 1, 2016
2 parents 53a4f25 + b7cc0d7 commit 6b0ad8a
Show file tree
Hide file tree
Showing 11 changed files with 85 additions and 14 deletions.
13 changes: 13 additions & 0 deletions src/vnsw/agent/pkt/flow_entry.cc
Expand Up @@ -286,6 +286,7 @@ void FlowData::Reset() {
ecmp_rpf_nh_ = 0;
acl_assigned_vrf_index_ = VrfEntry::kInvalidIndex;
qos_config_idx = AgentQosConfigTable::kInvalidIndex;
ttl = 0;
}

static std::vector<std::string> MakeList(const VnListType &ilist) {
Expand Down Expand Up @@ -581,6 +582,12 @@ void FlowEntry::InitFwdFlow(const PktFlowInfo *info, const PktInfo *pkt,
SetRpfNH(flow_table_, ctrl->rt_);
}

if (info->bgp_router_service_flow) {
if (info->ttl == 1) {
data_.ttl = BGP_SERVICE_TTL_FWD_FLOW;
}
}

data_.flow_source_vrf = info->flow_source_vrf;
data_.flow_dest_vrf = info->flow_dest_vrf;
data_.flow_source_plen_map = info->flow_source_plen_map;
Expand Down Expand Up @@ -651,6 +658,12 @@ void FlowEntry::InitRevFlow(const PktFlowInfo *info, const PktInfo *pkt,
SetRpfNH(flow_table_, ctrl->rt_);
}

if (info->bgp_router_service_flow) {
if (info->ttl == 1) {
data_.ttl = BGP_SERVICE_TTL_REV_FLOW;
}
}

data_.flow_source_vrf = info->flow_dest_vrf;
data_.flow_dest_vrf = info->flow_source_vrf;
data_.flow_source_plen_map = info->flow_dest_plen_map;
Expand Down
1 change: 1 addition & 0 deletions src/vnsw/agent/pkt/flow_entry.h
Expand Up @@ -280,6 +280,7 @@ struct FlowData {
uint32_t dest_vrf;
uint32_t component_nh_idx;
uint32_t bgp_as_a_service_port;
uint32_t ttl;

// Stats
uint8_t source_plen;
Expand Down
1 change: 1 addition & 0 deletions src/vnsw/agent/pkt/pkt_flow_info.cc
Expand Up @@ -822,6 +822,7 @@ void PktFlowInfo::BgpRouterServiceFromVm(const PktInfo *pkt, PktControlInfo *in,
out->rt_ = FlowEntry::GetUcRoute(out->vrf_, nat_server);
out->intf_ = agent->vhost_interface();
out->nh_ = out->intf_->flow_key_nh()->id();
ttl = pkt->ttl;
return;
}

Expand Down
4 changes: 3 additions & 1 deletion src/vnsw/agent/pkt/pkt_flow_info.h
Expand Up @@ -54,7 +54,7 @@ class PktFlowInfo {
trap_rev_flow(false), fip_snat(false), fip_dnat(false), snat_fip(),
short_flow_reason(0), peer_vrouter(), tunnel_type(TunnelType::INVALID),
flood_unknown_unicast(false), bgp_router_service_flow(false),
alias_ip_flow(false) {
alias_ip_flow(false), ttl(0) {
}

static bool ComputeDirection(const Interface *intf);
Expand Down Expand Up @@ -190,6 +190,8 @@ class PktFlowInfo {

// Alias IP flow
bool alias_ip_flow;
//TTL of nat'd flow especially bgp-service flows
uint8_t ttl;
};

#endif // __agent_pkt_flow_info_h_
14 changes: 8 additions & 6 deletions src/vnsw/agent/pkt/pkt_handler.cc
Expand Up @@ -376,6 +376,7 @@ int PktHandler::ParseIpPacket(PktInfo *pkt_info, PktType::Type &pkt_type,
pkt_info->ip_saddr = IpAddress(Ip4Address(ntohl(ip->ip_src.s_addr)));
pkt_info->ip_daddr = IpAddress(Ip4Address(ntohl(ip->ip_dst.s_addr)));
pkt_info->ip_proto = ip->ip_p;
pkt_info->ttl = ip->ip_ttl;
len += (ip->ip_hl << 2);
} else if (pkt_info->ether_type == ETHERTYPE_IPV6) {
pkt_info->family = Address::INET6;
Expand All @@ -393,6 +394,7 @@ int PktHandler::ParseIpPacket(PktInfo *pkt_info, PktType::Type &pkt_type,
addr[i] = ip->ip6_dst.s6_addr[i];
}
pkt_info->ip_daddr = IpAddress(Ip6Address(addr));
pkt_info->ttl = ip->ip6_hlim;

// Look for known transport headers. Fallback to the last header if
// no known header is found
Expand Down Expand Up @@ -975,17 +977,17 @@ PktInfo::PktInfo(const PacketBufferPtr &buff) :
pkt(buff->data()), len(buff->data_len()), max_pkt_len(buff->buffer_len()),
data(), ipc(), family(Address::UNSPEC), type(PktType::INVALID), agent_hdr(),
ether_type(-1), ip_saddr(), ip_daddr(), ip_proto(), sport(), dport(),
tcp_ack(false), tunnel(), l3_forwarding(false), l3_label(false), eth(),
arp(), ip(), ip6(), packet_buffer_(buff) {
ttl(0), tcp_ack(false), tunnel(), l3_forwarding(false),
l3_label(false), eth(), arp(), ip(), ip6(), packet_buffer_(buff) {
transp.tcp = 0;
}

PktInfo::PktInfo(const PacketBufferPtr &buff, const AgentHdr &hdr) :
pkt(buff->data()), len(buff->data_len()), max_pkt_len(buff->buffer_len()),
data(), ipc(), family(Address::UNSPEC), type(PktType::INVALID),
agent_hdr(hdr), ether_type(-1), ip_saddr(), ip_daddr(), ip_proto(), sport(),
dport(), tcp_ack(false), tunnel(), l3_forwarding(false), l3_label(false),
eth(), arp(), ip(), ip6(), packet_buffer_(buff) {
dport(), ttl(0), tcp_ack(false), tunnel(), l3_forwarding(false),
l3_label(false), eth(), arp(), ip(), ip6(), packet_buffer_(buff) {
transp.tcp = 0;
}

Expand All @@ -994,7 +996,7 @@ PktInfo::PktInfo(Agent *agent, uint32_t buff_len, PktHandler::PktModuleName mod,
module(mod),
len(), max_pkt_len(), data(), ipc(), family(Address::UNSPEC),
type(PktType::INVALID), agent_hdr(), ether_type(-1), ip_saddr(), ip_daddr(),
ip_proto(), sport(), dport(), tcp_ack(false), tunnel(),
ip_proto(), sport(), dport(), ttl(0), tcp_ack(false), tunnel(),
l3_forwarding(false), l3_label(false), eth(), arp(), ip(), ip6() {

packet_buffer_ = agent->pkt()->packet_buffer_manager()->Allocate
Expand All @@ -1010,7 +1012,7 @@ PktInfo::PktInfo(PktHandler::PktModuleName mod, InterTaskMsg *msg) :
module(mod),
pkt(), len(), max_pkt_len(0), data(), ipc(msg), family(Address::UNSPEC),
type(PktType::MESSAGE), agent_hdr(), ether_type(-1), ip_saddr(), ip_daddr(),
ip_proto(), sport(), dport(), tcp_ack(false), tunnel(),
ip_proto(), sport(), dport(), ttl(0), tcp_ack(false), tunnel(),
l3_forwarding(false), l3_label(false), eth(), arp(), ip(), ip6(), packet_buffer_() {
transp.tcp = 0;
}
Expand Down
4 changes: 4 additions & 0 deletions src/vnsw/agent/pkt/pkt_handler.h
Expand Up @@ -38,6 +38,9 @@
#define IPC_HDR_LEN (sizeof(struct ether_header) + sizeof(struct agent_hdr))
#define VLAN_PROTOCOL 0x8100
#define DEFAULT_IP_TTL 64
//Ideally VM is one hop away but traffic gets routed so use 2.
#define BGP_SERVICE_TTL_REV_FLOW 2
#define BGP_SERVICE_TTL_FWD_FLOW 255
#define DEFAULT_IP_ID 0
#define VLAN_HDR_LEN 4

Expand Down Expand Up @@ -350,6 +353,7 @@ struct PktInfo {
uint8_t ip_proto;
uint32_t sport;
uint32_t dport;
uint32_t ttl;

bool tcp_ack;
TunnelInfo tunnel;
Expand Down
44 changes: 44 additions & 0 deletions src/vnsw/agent/pkt/test/test_bgp_service.cc
Expand Up @@ -7,6 +7,7 @@
#include "test_pkt_util.h"
#include "pkt/flow_proto.h"
#include "pkt/flow_mgmt.h"
#include "pkt/pkt_handler.h"
#include <base/task.h>
#include <base/test/task_test_util.h>

Expand Down Expand Up @@ -83,6 +84,49 @@ class BgpServiceTest : public ::testing::Test {
BgpPeer *peer;
};

//TTL 1
TEST_F(BgpServiceTest, Test_ttl_1) {
AddAap("vnet1", 1, Ip4Address::from_string("10.10.10.10"), "00:00:01:01:01:01");
peer = CreateBgpPeer("127.0.0.1", "remote");
client->WaitForIdle();

TxTcpPacket(VmInterfaceGet(1)->id(), "10.10.10.10", "1.1.1.1", 10000, 179,
false, 1, 1, 1);
client->WaitForIdle();
FlowEntry *fe = FlowGet(VmInterfaceGet(1)->flow_key_nh()->id(),
"10.10.10.10", "1.1.1.1", 6, 10000, 179);
EXPECT_TRUE(fe != NULL);
EXPECT_TRUE(fe->reverse_flow_entry() != NULL);
EXPECT_TRUE(fe->is_flags_set(FlowEntry::BgpRouterService));
EXPECT_TRUE(fe->data().ttl == BGP_SERVICE_TTL_FWD_FLOW);
EXPECT_TRUE(fe->reverse_flow_entry()->data().ttl ==
BGP_SERVICE_TTL_REV_FLOW);

DeleteBgpPeer(peer);
client->WaitForIdle();
}

//TTL 64
TEST_F(BgpServiceTest, Test_ttl_2) {
AddAap("vnet1", 1, Ip4Address::from_string("10.10.10.10"), "00:00:01:01:01:01");
peer = CreateBgpPeer("127.0.0.1", "remote");
client->WaitForIdle();

TxTcpPacket(VmInterfaceGet(1)->id(), "10.10.10.10", "1.1.1.1", 10000, 179,
false, 1, 1, 64);
client->WaitForIdle();
FlowEntry *fe = FlowGet(VmInterfaceGet(1)->flow_key_nh()->id(),
"10.10.10.10", "1.1.1.1", 6, 10000, 179);
EXPECT_TRUE(fe != NULL);
EXPECT_TRUE(fe->reverse_flow_entry() != NULL);
EXPECT_TRUE(fe->is_flags_set(FlowEntry::BgpRouterService));
EXPECT_TRUE(fe->data().ttl == 0);
EXPECT_TRUE(fe->reverse_flow_entry()->data().ttl == 0);

DeleteBgpPeer(peer);
client->WaitForIdle();
}

TEST_F(BgpServiceTest, Test_1) {
peer = CreateBgpPeer("127.0.0.1", "remote");
client->WaitForIdle();
Expand Down
9 changes: 5 additions & 4 deletions src/vnsw/agent/pkt/test/test_pkt_util.cc
Expand Up @@ -101,20 +101,21 @@ void MakeSctpPacket(PktGen *pkt, int ifindex, const char *sip,

void MakeTcpPacket(PktGen *pkt, int ifindex, const char *sip,
const char *dip, uint16_t sport, uint16_t dport, bool ack,
int hash_id, uint32_t vrf_id) {
int hash_id, uint32_t vrf_id, int ttl) {
pkt->AddEthHdr("00:00:00:00:00:01", "00:00:00:00:00:02", 0x800);
pkt->AddAgentHdr(ifindex, AgentHdr::TRAP_FLOW_MISS, hash_id, vrf_id);
pkt->AddEthHdr("00:00:5E:00:01:00", "00:00:00:00:00:01", 0x800);
pkt->AddIpHdr(sip, dip, IPPROTO_TCP);
pkt->AddIpHdr(sip, dip, IPPROTO_TCP, false, ttl);
pkt->AddTcpHdr(sport, dport, false, false, ack, 64);

}

void TxTcpPacket(int ifindex, const char *sip, const char *dip,
uint16_t sport, uint16_t dport, bool ack, int hash_id,
uint32_t vrf_id) {
uint32_t vrf_id, int ttl) {
PktGen *pkt = new PktGen();
MakeTcpPacket(pkt, ifindex, sip, dip, sport, dport, ack, hash_id, vrf_id);
MakeTcpPacket(pkt, ifindex, sip, dip, sport, dport, ack, hash_id, vrf_id,
ttl);
uint8_t *ptr(new uint8_t[pkt->GetBuffLen()]);
memcpy(ptr, pkt->GetBuff(), pkt->GetBuffLen());
client->agent_init()->pkt0()->ProcessFlowPacket(ptr, pkt->GetBuffLen(),
Expand Down
4 changes: 2 additions & 2 deletions src/vnsw/agent/pkt/test/test_pkt_util.h
Expand Up @@ -31,15 +31,15 @@ extern void TxUdpPacket(int ifindex, const char *sip, const char *dip,

extern void MakeTcpPacket(PktGen *pkt, int ifindex, const char *sip,
const char *dip, uint16_t sport, uint16_t dport,
bool ack, int hash_id, uint32_t vrf_id);
bool ack, int hash_id, uint32_t vrf_id, int ttl = 0);

extern void MakeSctpPacket(PktGen *pkt, int ifindex, const char *sip,
const char *dip, uint16_t sport, uint16_t dport,
int hash_id, uint32_t vrf_id);

extern void TxTcpPacket(int ifindex, const char *sip, const char *dip,
uint16_t sport, uint16_t dport, bool ack, int hash_id = 1,
uint32_t vrf_id = -1);
uint32_t vrf_id = -1, int ttl = 0);

extern void MakeIpMplsPacket(PktGen *pkt, int ifindex, const char *out_sip,
const char *out_dip, uint32_t label,
Expand Down
3 changes: 2 additions & 1 deletion src/vnsw/agent/test/pkt_gen.h
Expand Up @@ -298,7 +298,7 @@ class PktGen {
};

void AddIpHdr(const char *sip, const char *dip, uint16_t proto,
bool fragment = false) {
bool fragment = false, int ttl = 0) {
struct ip *ip = (struct ip *)(buff + len);

ip->ip_hl = 5;
Expand All @@ -307,6 +307,7 @@ class PktGen {
ip->ip_src.s_addr = inet_addr(sip);
ip->ip_dst.s_addr = inet_addr(dip);
ip->ip_p = proto;
ip->ip_ttl = ttl;
if (fragment)
ip->ip_off = htons(IP_MF);
len += sizeof(struct ip);
Expand Down
2 changes: 2 additions & 0 deletions src/vnsw/agent/vrouter/ksync/flowtable_ksync.cc
Expand Up @@ -327,6 +327,7 @@ int FlowTableKSyncEntry::Encode(sandesh_op::type op, char *buf, int buf_len) {
flags |= VR_FLOW_FLAG_DPAT;
}
}

//TODO Seperate flags for BgpRouterService??
if (nat_flow->is_flags_set(FlowEntry::LinkLocalBindLocalSrcPort) ||
nat_flow->is_flags_set(FlowEntry::BgpRouterService)) {
Expand Down Expand Up @@ -370,6 +371,7 @@ int FlowTableKSyncEntry::Encode(sandesh_op::type op, char *buf, int buf_len) {
req.set_fr_action(action);
req.set_fr_drop_reason(drop_reason);
req.set_fr_qos_id(qos_config_idx);
req.set_fr_ttl(flow_entry_->data().ttl);
}

FlowProto *proto = ksync_obj_->ksync()->agent()->pkt()->get_flow_proto();
Expand Down

0 comments on commit 6b0ad8a

Please sign in to comment.