From 88335ed0ac8e38836eeed4b360fdcb1a32ae2ce7 Mon Sep 17 00:00:00 2001 From: Aleksandr Stepanov Date: Tue, 19 Nov 2024 16:13:01 +0300 Subject: [PATCH] Changes to the ipv4 connectivity task: - For route tunnel, the ability to set the IpIp type (new flow type) has been added - In controlplane.conf, the ability to set the tunnel type for writing route table has been added --- .../076_rfc_5549_route_tunnel/001-expect.pcap | Bin 366 -> 148 bytes .../076_rfc_5549_route_tunnel/001-send.pcap | Bin 330 -> 228 bytes .../076_rfc_5549_route_tunnel/002-expect.pcap | Bin 0 -> 456 bytes .../076_rfc_5549_route_tunnel/002-send.pcap | Bin 0 -> 272 bytes .../076_rfc_5549_route_tunnel/autotest.yaml | 19 +++---- .../controlplane.conf | 48 ++++++++++++++---- .../076_rfc_5549_route_tunnel/gen.py | 24 ++++++--- cli/rib.h | 2 +- common/define.h | 4 ++ common/type.h | 3 ++ controlplane/base.h | 1 + controlplane/configconverter.cpp | 18 +++++++ controlplane/configparser.cpp | 1 + controlplane/dregress.cpp | 2 +- controlplane/rib.cpp | 19 +++++-- controlplane/route.cpp | 4 +- dataplane/globalbase.cpp | 8 ++- dataplane/report.cpp | 5 ++ dataplane/worker.cpp | 43 +++++++++------- 19 files changed, 147 insertions(+), 54 deletions(-) create mode 100644 autotest/units/001_one_port/076_rfc_5549_route_tunnel/002-expect.pcap create mode 100644 autotest/units/001_one_port/076_rfc_5549_route_tunnel/002-send.pcap diff --git a/autotest/units/001_one_port/076_rfc_5549_route_tunnel/001-expect.pcap b/autotest/units/001_one_port/076_rfc_5549_route_tunnel/001-expect.pcap index a42bec7401aa94692fc47844c6a3d769a8bf282c..425b83188dd52003459705da511b99831a60637e 100644 GIT binary patch literal 148 zcmca|c+)~A1{MYw`2U}Qff2?5(t1z~7Gh)&R5Er6ZDe3b;b3rOV2}YRwP#E_&Bet4 cM2t)v4BvtJ5dcLu6I}NRWZkJy-Ar)Z08{-D-v9sr literal 366 zcmca|c+)~A1{MYw`2U}Qff2?5(n(MZ7Gh!$R5Er6ZDe3L(RMchB%~qeprj-y$iN_E z5>~;;cuMe;U`Gd7EsS7%l_U9@K?BHjIr!g|fk6gjygg&p1CRnBlaYhrJJ3!9z-?oq t08kYXHXgWwWTPP5#`7RMNV72kq=m4JOc#ovHhME6`LXf=NIMgf9|7j?I-mdm diff --git a/autotest/units/001_one_port/076_rfc_5549_route_tunnel/001-send.pcap b/autotest/units/001_one_port/076_rfc_5549_route_tunnel/001-send.pcap index cb6a66eb92e84ac9ffae22ba7167e64b22eb981d..9cb86fd8a03994163c9dc72bc4fc33a671282fdf 100644 GIT binary patch literal 228 zcmca|c+)~A1{MYw`2U}Qff2?5(qT}{AgE;Q5(<*wVQ6Gv)M>k$0OH87IJmfg7;wO7 qYz$|E7>uq!RUjiB7*kJkaWMc9BNGS1cc488KuudxptdlfT#fG8xusHB9% zV>olh6{reiqyuB+1CR`m$;iR*9cT{%;I)O3C|d;Kwwwo 3333::2" - cli: - - neighbor insert route0 kni0.200 c0de::200:1 00:00:00:00:00:02 - - neighbor flush -- cli: - - rib static insert default 1.0.0.0/24 8888::1 1100 10000 1 1 + - rib static insert default 1.0.0.0/24 4444::1 1100 10000 1 1 - rib_insert: attribute: protocol: autotest @@ -12,19 +10,18 @@ steps: large_communities: - 13238:1:1 prefixes: - - nexthop: 8888::2 + - nexthop: 5555::1 prefix: 2.0.0.0/24 - path_information: 88.88.88.1:10001 + path_information: 55.55.55.1:10001 labels: - 1200 -- ipv6Update: - - "::/0 -> c0de::200:1" - cli: - rib prefixes - - route tunnel lookup route0 1.0.0.1 - - route tunnel lookup route0 2.0.0.1 - sendPackets: - port: kni0 send: 001-send.pcap expect: 001-expect.pcap - +- sendPackets: + - port: kni0 + send: 002-send.pcap + expect: 002-expect.pcap diff --git a/autotest/units/001_one_port/076_rfc_5549_route_tunnel/controlplane.conf b/autotest/units/001_one_port/076_rfc_5549_route_tunnel/controlplane.conf index f3a7e8c0..4dad23f1 100644 --- a/autotest/units/001_one_port/076_rfc_5549_route_tunnel/controlplane.conf +++ b/autotest/units/001_one_port/076_rfc_5549_route_tunnel/controlplane.conf @@ -5,16 +5,35 @@ "physicalPort": "kni0", "vlanId": "100", "macAddress": "00:11:22:33:44:55", - "nextModule": "acl0" + "nextModule": "acl_route_tunnel" }, "lp0.200": { "type": "logicalPort", "physicalPort": "kni0", "vlanId": "200", "macAddress": "00:11:22:33:44:55", - "nextModule": "acl0" + "nextModule": "acl_route_tunnel_ipip" }, - "acl0": { + "lp0.300": { + "type": "logicalPort", + "physicalPort": "kni0", + "vlanId": "300", + "macAddress": "00:11:22:33:44:55", + "nextModule": "acl_decap" + }, + "acl_route_tunnel": { + "type": "acl", + "nextModules": [ + "route0:tunnel" + ] + }, + "acl_route_tunnel_ipip": { + "type": "acl", + "nextModules": [ + "route0:tunnel_ipip" + ] + }, + "acl_decap": { "type": "acl", "nextModules": [ "decap0" @@ -23,28 +42,39 @@ "decap0": { "type": "decap", "ipv6DestinationPrefixes": [ - "2222::cccc/128" + "3333::1" ], - "ipv6_enabled": true, - "nextModule": "route0:tunnel" + "nextModule": "route0" }, "route0": { "type": "route", "ipv4SourceAddress": "10.50.0.1", - "ipv6SourceAddress": "2222:1111:0:1234:5678:0101:ca11:ca11", + "ipv6SourceAddress": "3333::1", "udpDestinationPort": 6635, "interfaces": { "kni0.100": { "ipAddresses": [ - "11.0.0.2/24" + "10.0.1.1/24" ], + "neighborIPv4Address": "10.0.1.2", + "neighborMacAddress": "00:00:00:00:00:01", "nextModule": "lp0.100" }, "kni0.200": { "ipAddresses": [ - "c0de::200:2/96" + "10.0.2.1/24" ], + "neighborIPv4Address": "10.0.2.2", + "neighborMacAddress": "00:00:00:00:00:02", "nextModule": "lp0.200" + }, + "kni0.300": { + "ipAddresses": [ + "3333::1/96" + ], + "neighborIPv6Address": "3333::2", + "neighborMacAddress": "00:00:00:00:00:03", + "nextModule": "lp0.300" } }, "peers": { diff --git a/autotest/units/001_one_port/076_rfc_5549_route_tunnel/gen.py b/autotest/units/001_one_port/076_rfc_5549_route_tunnel/gen.py index 1bbb7c13..394b2e91 100755 --- a/autotest/units/001_one_port/076_rfc_5549_route_tunnel/gen.py +++ b/autotest/units/001_one_port/076_rfc_5549_route_tunnel/gen.py @@ -22,12 +22,24 @@ def write_pcap(filename, *packetsList): wrpcap(filename, [p for p in packets], append=True) +# Check decapsulator for IpIp tunnel write_pcap("001-send.pcap", - Ether(dst="00:11:22:33:44:55", src="00:00:00:00:00:01")/Dot1Q(vlan=100)/IPv6(dst="2222::cccc", src="::1")/IP(dst="1.0.0.1", src="0.0.0.0", ttl=64)/ICMP(), - Ether(dst="00:11:22:33:44:55", src="00:00:00:00:00:01")/Dot1Q(vlan=100)/IPv6(dst="2222::cccc", src="::1", fl=1)/IP(dst="1.0.0.1", src="0.0.0.0", ttl=64, tos=17)/ICMP(), - Ether(dst="00:11:22:33:44:55", src="00:00:00:00:00:01")/Dot1Q(vlan=100)/IPv6(dst="2222::cccc", src="::1")/IP(dst="2.0.0.1", src="0.0.0.0", ttl=64)/ICMP()) + Ether(dst="00:11:22:33:44:55", src="00:00:00:00:0c:00")/Dot1Q(vlan=300)/IPv6(dst="3333::1", src="4444::1")/IP(dst="10.0.1.2", src="10.10.0.10", ttl=64)/ICMP(), + Ether(dst="00:11:22:33:44:55", src="00:00:00:00:0c:00")/Dot1Q(vlan=300)/IPv6(dst="3333::1", src="4444::1")/IP(dst="10.0.2.2", src="10.10.0.10", ttl=64)/ICMP()) write_pcap("001-expect.pcap", - Ether(dst="00:00:00:00:00:02", src="00:11:22:33:44:55")/Dot1Q(vlan=200)/IPv6(dst="8888::1", src="2222:1111:0:1234:5678:0101:ca11:ca11")/UDP(dport=6635, sport=0xaa6c | 0xc000, chksum=0)/MPLS(label=1100, ttl=255)/IP(dst="1.0.0.1", src="0.0.0.0", ttl=63)/ICMP(), - Ether(dst="00:00:00:00:00:02", src="00:11:22:33:44:55")/Dot1Q(vlan=200)/IPv6(dst="8888::1", src="2222:1111:0:1234:5678:0101:ca11:ca11", tc=17)/UDP(dport=6635, sport=0x00d4 | 0xc000, chksum=0)/MPLS(label=1100, ttl=255)/IP(dst="1.0.0.1", src="0.0.0.0", ttl=63, tos=17)/ICMP(), - Ether(dst="00:00:00:00:00:02", src="00:11:22:33:44:55")/Dot1Q(vlan=200)/IPv6(dst="8888::2", src="2222:1111:0:1234:5678:0101:ca11:ca11")/UDP(dport=6635, sport=0x1072 | 0xc000, chksum=0)/MPLS(label=1200, ttl=255)/IP(dst="2.0.0.1", src="0.0.0.0", ttl=63)/ICMP()) + Ether(dst="00:00:00:00:00:01", src="00:11:22:33:44:55")/Dot1Q(vlan=100)/IP(dst="10.0.1.2", src="10.10.0.10", ttl=63)/ICMP(), + Ether(dst="00:00:00:00:00:02", src="00:11:22:33:44:55")/Dot1Q(vlan=200)/IP(dst="10.0.2.2", src="10.10.0.10", ttl=63)/ICMP()) + +# Check route tunnel mpls over udp + tunnel ipip +write_pcap("002-send.pcap", + Ether(dst="00:11:22:33:44:55", src="00:00:00:00:00:01")/Dot1Q(vlan=100)/IP(dst="1.0.0.1", src="10.0.1.2", ttl=64)/ICMP(), + Ether(dst="00:11:22:33:44:55", src="00:00:00:00:00:01")/Dot1Q(vlan=100)/IP(dst="2.0.0.1", src="10.0.1.2", ttl=64)/ICMP(), + Ether(dst="00:11:22:33:44:55", src="00:00:00:00:00:02")/Dot1Q(vlan=200)/IP(dst="1.0.0.1", src="10.0.2.2", ttl=64)/ICMP(), + Ether(dst="00:11:22:33:44:55", src="00:00:00:00:00:02")/Dot1Q(vlan=200)/IP(dst="2.0.0.1", src="10.0.2.2", ttl=64)/ICMP()) + +write_pcap("002-expect.pcap", + Ether(dst="00:00:00:00:00:03", src="00:11:22:33:44:55")/Dot1Q(vlan=300)/IPv6(dst="4444::1", src="3333::1")/UDP(dport=6635, sport=0xca71, chksum=0)/MPLS(label=1100, ttl=255)/IP(dst="1.0.0.1", src="10.0.1.2", ttl=63)/ICMP(), + Ether(dst="00:00:00:00:00:03", src="00:11:22:33:44:55")/Dot1Q(vlan=300)/IPv6(dst="5555::1", src="3333::1")/UDP(dport=6635, sport=0xf06f, chksum=0)/MPLS(label=1200, ttl=255)/IP(dst="2.0.0.1", src="10.0.1.2", ttl=63)/ICMP(), + Ether(dst="00:00:00:00:00:03", src="00:11:22:33:44:55")/Dot1Q(vlan=300)/IPv6(dst="4444::1", src="3333::1")/IP(dst="1.0.0.1", src="10.0.2.2", ttl=63)/ICMP(), + Ether(dst="00:00:00:00:00:03", src="00:11:22:33:44:55")/Dot1Q(vlan=300)/IPv6(dst="5555::1", src="3333::1")/IP(dst="2.0.0.1", src="10.0.2.2", ttl=63)/ICMP()) diff --git a/cli/rib.h b/cli/rib.h index aeb8880c..3a0ee51b 100644 --- a/cli/rib.h +++ b/cli/rib.h @@ -278,7 +278,7 @@ void insert(const std::string& vrf, std::set large_communities; if (weight) { - large_communities.emplace(13238, 1, *weight); ///< @todo: DEFINE + large_communities.emplace(YANET_DEFAULT_BGP_AS, 1, *weight); } common::icp::rib_update::insert insert = {"static", diff --git a/common/define.h b/common/define.h index 03846a26..5547c4e8 100644 --- a/common/define.h +++ b/common/define.h @@ -104,6 +104,10 @@ extern LogPriority logPriority; #define YANET_RIB_PRIORITY_ROUTE_TUNNEL_FALLBACK ((uint32_t)11000) #define YANET_RIB_PRIORITY_ROUTE_REPEAT ((uint32_t)12000) +#define YANET_DEFAULT_BGP_AS 13238 +#define YANET_STATIC_ROUTE_TUNNEL_LABEL 3199 +#define YANET_STATIC_ROUTE_TUNNEL_PATH_INFORMATION "127.0.0.1:10000" + #define YANET_NETWORK_FLAG_FRAGMENT ((uint8_t)(1u << 0)) #define YANET_NETWORK_FLAG_NOT_FIRST_FRAGMENT ((uint8_t)(1u << 1)) #define YANET_NETWORK_FLAG_HAS_EXTENSION ((uint8_t)(1u << 2)) diff --git a/common/type.h b/common/type.h index 898a3f11..dca6ac50 100644 --- a/common/type.h +++ b/common/type.h @@ -2135,6 +2135,7 @@ enum class eFlowType : uint8_t route, route_local, route_tunnel, + route_tunnel_ipip, acl_egress, dregress, controlPlane, @@ -2201,6 +2202,8 @@ inline const char* eFlowType_toString(eFlowType t) return "route_local"; case eFlowType::route_tunnel: return "route_tunnel"; + case eFlowType::route_tunnel_ipip: + return "route_tunnel_ipip"; case eFlowType::acl_egress: return "acl_egress"; case eFlowType::dregress: diff --git a/controlplane/base.h b/controlplane/base.h index 6b06b13d..0fb2cea2 100644 --- a/controlplane/base.h +++ b/controlplane/base.h @@ -423,6 +423,7 @@ class base_rib public: ip_prefix_t prefix; ip_address_t nexthop; + bool is_tunnel; }; // diff --git a/controlplane/configconverter.cpp b/controlplane/configconverter.cpp index 4d32fe61..3ea5eb73 100644 --- a/controlplane/configconverter.cpp +++ b/controlplane/configconverter.cpp @@ -124,6 +124,15 @@ void config_converter_t::convertToFlow(const std::string& nextModule, throw error_result_t(eResult::invalidFlow, "invalid entry (tunnel not configured)"); } } + else if (entry == "tunnel_ipip") + { + flow.type = common::globalBase::eFlowType::route_tunnel_ipip; + + if (!it->second.tunnel_enabled) + { + throw error_result_t(eResult::invalidFlow, "invalid entry (tunnel not configured)"); + } + } else { throw error_result_t(eResult::invalidFlow, "invalid entry: " + entry); @@ -460,6 +469,7 @@ void config_converter_t::processDecap() if (decap.flow.type != common::globalBase::eFlowType::route && decap.flow.type != common::globalBase::eFlowType::route_tunnel && + decap.flow.type != common::globalBase::eFlowType::route_tunnel_ipip && decap.flow.type != common::globalBase::eFlowType::controlPlane && decap.flow.type != common::globalBase::eFlowType::drop) { @@ -490,6 +500,7 @@ void config_converter_t::processNat64stateful() if (nat64stateful.flow.type != common::globalBase::eFlowType::route && nat64stateful.flow.type != common::globalBase::eFlowType::route_tunnel && + nat64stateful.flow.type != common::globalBase::eFlowType::route_tunnel_ipip && nat64stateful.flow.type != common::globalBase::eFlowType::controlPlane && nat64stateful.flow.type != common::globalBase::eFlowType::drop) { @@ -515,6 +526,7 @@ void config_converter_t::processTun64() if (tunnel.flow.type != common::globalBase::eFlowType::route && tunnel.flow.type != common::globalBase::eFlowType::route_tunnel && + tunnel.flow.type != common::globalBase::eFlowType::route_tunnel_ipip && tunnel.flow.type != common::globalBase::eFlowType::controlPlane && tunnel.flow.type != common::globalBase::eFlowType::drop) { @@ -539,6 +551,7 @@ void config_converter_t::processNat64() if (nat64stateless.flow.type != common::globalBase::eFlowType::route && nat64stateless.flow.type != common::globalBase::eFlowType::route_tunnel && + nat64stateless.flow.type != common::globalBase::eFlowType::route_tunnel_ipip && nat64stateless.flow.type != common::globalBase::eFlowType::controlPlane && nat64stateless.flow.type != common::globalBase::eFlowType::drop) { @@ -598,6 +611,7 @@ void config_converter_t::processNat46clat() if (nat46clat.flow.type != common::globalBase::eFlowType::route && nat46clat.flow.type != common::globalBase::eFlowType::route_tunnel && + nat46clat.flow.type != common::globalBase::eFlowType::route_tunnel_ipip && nat46clat.flow.type != common::globalBase::eFlowType::controlPlane && nat46clat.flow.type != common::globalBase::eFlowType::drop) { @@ -768,6 +782,10 @@ void config_converter_t::processAcl() { acl_rules_route_forward(acl, nextModule); } + else if (entry == "tunnel_ipip") + { + acl_rules_route_forward(acl, nextModule); + } else { acl_rules_route_local(acl, nextModule); diff --git a/controlplane/configparser.cpp b/controlplane/configparser.cpp index af331d5e..2a83ba76 100644 --- a/controlplane/configparser.cpp +++ b/controlplane/configparser.cpp @@ -1906,6 +1906,7 @@ void config_parser_t::loadConfig_rib(controlplane::base_t& baseNext, controlplane::base_rib base_rib; base_rib.prefix = json_rib_item["prefix"].get(); base_rib.nexthop = json_rib_item["nexthop"].get(); + base_rib.is_tunnel = (exist(json_rib_item, "tunnel") && json_rib_item["tunnel"].get()); vrf.emplace_back(std::move(base_rib)); } diff --git a/controlplane/dregress.cpp b/controlplane/dregress.cpp index c5a10764..5b4419a6 100644 --- a/controlplane/dregress.cpp +++ b/controlplane/dregress.cpp @@ -82,7 +82,7 @@ void dregress_t::prefix_insert(const std::tuple& vrf_prio { try { - communities.emplace(13238, std::stoll(path_info.substr(pi_it + 1), nullptr, 0)); ///< @todo: remove 13238, and use RD + communities.emplace(YANET_DEFAULT_BGP_AS, std::stoll(path_info.substr(pi_it + 1), nullptr, 0)); } catch (...) { diff --git a/controlplane/rib.cpp b/controlplane/rib.cpp index c66e21ed..5f69f7e9 100644 --- a/controlplane/rib.cpp +++ b/controlplane/rib.cpp @@ -95,10 +95,21 @@ void rib_t::reload(const controlplane::base_t& base_prev, for (const auto& rib_item : rib_items) { - auto& prefixes = std::get<3>(request_insert)[{ip_address_t("::"), "", 0, {}, {}, {}, 0}] - [""] - [rib_item.nexthop]; - prefixes.emplace_back(rib_item.prefix, "", std::vector()); + if (rib_item.is_tunnel) + { + common::large_community_t large_community(YANET_DEFAULT_BGP_AS, 1, 1); + auto& prefixes = std::get<3>(request_insert)[{ip_address_t("::"), "", 0, {}, {}, {large_community}, 0}] + [""] + [rib_item.nexthop]; + prefixes.emplace_back(rib_item.prefix, YANET_STATIC_ROUTE_TUNNEL_PATH_INFORMATION, std::vector(1, YANET_STATIC_ROUTE_TUNNEL_LABEL)); + } + else + { + auto& prefixes = std::get<3>(request_insert)[{ip_address_t("::"), "", 0, {}, {}, {}, 0}] + [""] + [rib_item.nexthop]; + prefixes.emplace_back(rib_item.prefix, "", std::vector()); + } } request.emplace_back(std::move(request_insert)); diff --git a/controlplane/route.cpp b/controlplane/route.cpp index 4d7b066c..13f4bfa3 100644 --- a/controlplane/route.cpp +++ b/controlplane/route.cpp @@ -231,13 +231,13 @@ void route_t::tunnel_prefix_update(const std::tuple& vrf_ for (const auto& large_community : large_communities) { - if (large_community.value[0] == 13238 && ///< @todo: DEFINE + if (large_community.value[0] == YANET_DEFAULT_BGP_AS && large_community.value[1] == 1) ///< @todo: DEFINE { weight = large_community.value[2]; } - if (large_community.value[0] == 13238 && ///< @todo: DEFINE + if (large_community.value[0] == YANET_DEFAULT_BGP_AS && large_community.value[1] == 1000) ///< @todo: DEFINE { override_length = large_community.value[2]; diff --git a/dataplane/globalbase.cpp b/dataplane/globalbase.cpp index e2327ff1..dda24bd7 100644 --- a/dataplane/globalbase.cpp +++ b/dataplane/globalbase.cpp @@ -660,7 +660,8 @@ static bool checkFlow(const common::globalBase::tFlow& flow) } } else if (flow.type == common::globalBase::eFlowType::route || - flow.type == common::globalBase::eFlowType::route_tunnel) + flow.type == common::globalBase::eFlowType::route_tunnel || + flow.type == common::globalBase::eFlowType::route_tunnel_ipip) { if (flow.data.routeId >= CONFIG_YADECAP_ROUTES_SIZE) { @@ -862,6 +863,7 @@ eResult generation::tun64_update(const common::idp::updateGlobalBase::tun64_upda if (flow.type != common::globalBase::eFlowType::route && flow.type != common::globalBase::eFlowType::route_tunnel && + flow.type != common::globalBase::eFlowType::route_tunnel_ipip && flow.type != common::globalBase::eFlowType::controlPlane && flow.type != common::globalBase::eFlowType::drop) { @@ -964,6 +966,7 @@ eResult generation::updateDecap(const common::idp::updateGlobalBase::updateDecap } if (flow.type != common::globalBase::eFlowType::route && flow.type != common::globalBase::eFlowType::route_tunnel && + flow.type != common::globalBase::eFlowType::route_tunnel_ipip && flow.type != common::globalBase::eFlowType::controlPlane && flow.type != common::globalBase::eFlowType::drop) { @@ -1134,6 +1137,7 @@ eResult generation::nat64stateful_update(const common::idp::updateGlobalBase::na } if (flow.type != common::globalBase::eFlowType::route && flow.type != common::globalBase::eFlowType::route_tunnel && + flow.type != common::globalBase::eFlowType::route_tunnel_ipip && flow.type != common::globalBase::eFlowType::controlPlane && flow.type != common::globalBase::eFlowType::drop) { @@ -1235,6 +1239,7 @@ eResult generation::updateNat64stateless(const common::idp::updateGlobalBase::up } if (flow.type != common::globalBase::eFlowType::route && flow.type != common::globalBase::eFlowType::route_tunnel && + flow.type != common::globalBase::eFlowType::route_tunnel_ipip && flow.type != common::globalBase::eFlowType::controlPlane && flow.type != common::globalBase::eFlowType::drop) { @@ -1343,6 +1348,7 @@ eResult generation::nat46clat_update(const common::idp::updateGlobalBase::nat46c if (flow.type != common::globalBase::eFlowType::route && flow.type != common::globalBase::eFlowType::route_tunnel && + flow.type != common::globalBase::eFlowType::route_tunnel_ipip && flow.type != common::globalBase::eFlowType::controlPlane && flow.type != common::globalBase::eFlowType::drop) { diff --git a/dataplane/report.cpp b/dataplane/report.cpp index ca8917bf..23b93dac 100644 --- a/dataplane/report.cpp +++ b/dataplane/report.cpp @@ -542,6 +542,11 @@ static inline nlohmann::json convertFlow(const common::globalBase::tFlow& flow) result["type"] = "route_tunnel"; result["id"] = flow.data.routeId; } + else if (flow.type == common::globalBase::eFlowType::route_tunnel_ipip) + { + result["type"] = "route_tunnel_ipip"; + result["id"] = flow.data.routeId; + } else if (flow.type == common::globalBase::eFlowType::acl_egress) { result["type"] = "acl_egress"; diff --git a/dataplane/worker.cpp b/dataplane/worker.cpp index dc9b7f7b..ed1457c5 100644 --- a/dataplane/worker.cpp +++ b/dataplane/worker.cpp @@ -1241,7 +1241,7 @@ inline void cWorker::logicalPort_ingress_flow(rte_mbuf* mbuf, { route_entry(mbuf); } - else if (flow.type == common::globalBase::eFlowType::route_tunnel) + else if (flow.type == common::globalBase::eFlowType::route_tunnel || flow.type == common::globalBase::eFlowType::route_tunnel_ipip) { route_tunnel_entry(mbuf); } @@ -1863,7 +1863,7 @@ inline void cWorker::acl_ingress_flow(rte_mbuf* mbuf, { route_entry(mbuf); } - else if (flow.type == common::globalBase::eFlowType::route_tunnel) + else if (flow.type == common::globalBase::eFlowType::route_tunnel || flow.type == common::globalBase::eFlowType::route_tunnel_ipip) { route_tunnel_entry(mbuf); } @@ -2040,7 +2040,7 @@ inline void cWorker::tun64_flow(rte_mbuf* mbuf, { route_entry(mbuf); } - else if (flow.type == common::globalBase::eFlowType::route_tunnel) + else if (flow.type == common::globalBase::eFlowType::route_tunnel || flow.type == common::globalBase::eFlowType::route_tunnel_ipip) { route_tunnel_entry(mbuf); } @@ -2110,7 +2110,7 @@ inline void cWorker::decap_flow(rte_mbuf* mbuf, { route_entry(mbuf); } - else if (flow.type == common::globalBase::eFlowType::route_tunnel) + else if (flow.type == common::globalBase::eFlowType::route_tunnel || flow.type == common::globalBase::eFlowType::route_tunnel_ipip) { route_tunnel_entry(mbuf); } @@ -2803,6 +2803,7 @@ inline void cWorker::route_tunnel_nexthop(rte_mbuf* mbuf, return; } + bool skip_udp_mpls = (metadata->flow == common::globalBase::eFlowType::route_tunnel_ipip); uint16_t payload_length; bool is_ipv4 = metadata->network_headerType == rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); if (is_ipv4 && !nexthop.is_ipv6) @@ -2810,9 +2811,10 @@ inline void cWorker::route_tunnel_nexthop(rte_mbuf* mbuf, rte_ipv4_hdr* ipv4HeaderInner = rte_pktmbuf_mtod_offset(mbuf, rte_ipv4_hdr*, metadata->network_headerOffset); /// @todo: mpls_header_t - rte_pktmbuf_prepend(mbuf, sizeof(rte_ipv4_hdr) + sizeof(rte_udp_hdr) + YADECAP_MPLS_HEADER_SIZE); + size_t size_mbuf = sizeof(rte_ipv4_hdr) + (skip_udp_mpls ? 0 : sizeof(rte_udp_hdr) + YADECAP_MPLS_HEADER_SIZE); + rte_pktmbuf_prepend(mbuf, size_mbuf); rte_memcpy(rte_pktmbuf_mtod(mbuf, char*), - rte_pktmbuf_mtod_offset(mbuf, char*, sizeof(rte_ipv4_hdr) + sizeof(rte_udp_hdr) + YADECAP_MPLS_HEADER_SIZE), + rte_pktmbuf_mtod_offset(mbuf, char*, size_mbuf), metadata->network_headerOffset); /// @todo: check for ethernetHeader or vlanHeader @@ -2823,11 +2825,11 @@ inline void cWorker::route_tunnel_nexthop(rte_mbuf* mbuf, ipv4Header->version_ihl = 0x45; ipv4Header->type_of_service = ipv4HeaderInner->type_of_service; - ipv4Header->total_length = rte_cpu_to_be_16((sizeof(rte_ipv4_hdr) + sizeof(rte_udp_hdr) + YADECAP_MPLS_HEADER_SIZE) + rte_be_to_cpu_16(ipv4HeaderInner->total_length)); + ipv4Header->total_length = rte_cpu_to_be_16(size_mbuf + rte_be_to_cpu_16(ipv4HeaderInner->total_length)); ipv4Header->packet_id = ipv4HeaderInner->packet_id; ipv4Header->fragment_offset = 0; ipv4Header->time_to_live = 64; - ipv4Header->next_proto_id = IPPROTO_UDP; + ipv4Header->next_proto_id = (skip_udp_mpls ? IPPROTO_IPIP : IPPROTO_UDP); ipv4Header->hdr_checksum = 0; ipv4Header->src_addr = route.ipv4AddressSource.address; ipv4Header->dst_addr = nexthop.nexthop_address.mapped_ipv4_address.address; @@ -2846,7 +2848,7 @@ inline void cWorker::route_tunnel_nexthop(rte_mbuf* mbuf, { rte_ipv4_hdr* ipv4HeaderInner = rte_pktmbuf_mtod_offset(mbuf, rte_ipv4_hdr*, metadata->network_headerOffset); vtc_flow = rte_cpu_to_be_32((0x6 << 28) | (ipv4HeaderInner->type_of_service << 20)); ///< @todo: flow label - payload_len = rte_cpu_to_be_16(sizeof(rte_udp_hdr) + YADECAP_MPLS_HEADER_SIZE + rte_be_to_cpu_16(ipv4HeaderInner->total_length)); + payload_len = rte_cpu_to_be_16((skip_udp_mpls ? 0 : sizeof(rte_udp_hdr) + YADECAP_MPLS_HEADER_SIZE) + rte_be_to_cpu_16(ipv4HeaderInner->total_length)); payload_length = rte_be_to_cpu_16(ipv4HeaderInner->total_length); } else @@ -2858,9 +2860,10 @@ inline void cWorker::route_tunnel_nexthop(rte_mbuf* mbuf, } /// @todo: mpls_header_t - rte_pktmbuf_prepend(mbuf, sizeof(rte_ipv6_hdr) + sizeof(rte_udp_hdr) + YADECAP_MPLS_HEADER_SIZE); + size_t size_mbuf = sizeof(rte_ipv6_hdr) + (skip_udp_mpls ? 0 : sizeof(rte_udp_hdr) + YADECAP_MPLS_HEADER_SIZE); + rte_pktmbuf_prepend(mbuf, size_mbuf); rte_memcpy(rte_pktmbuf_mtod(mbuf, char*), - rte_pktmbuf_mtod_offset(mbuf, char*, sizeof(rte_ipv6_hdr) + sizeof(rte_udp_hdr) + YADECAP_MPLS_HEADER_SIZE), + rte_pktmbuf_mtod_offset(mbuf, char*, size_mbuf), metadata->network_headerOffset); /// @todo: check for ethernetHeader or vlanHeader @@ -2872,7 +2875,7 @@ inline void cWorker::route_tunnel_nexthop(rte_mbuf* mbuf, ipv6Header->vtc_flow = vtc_flow; ipv6Header->payload_len = payload_len; - ipv6Header->proto = IPPROTO_UDP; + ipv6Header->proto = (skip_udp_mpls ? IPPROTO_IPIP : IPPROTO_UDP); ipv6Header->hop_limits = 64; rte_memcpy(ipv6Header->src_addr, route.ipv6AddressSource.bytes, 16); rte_memcpy(ipv6Header->dst_addr, nexthop.nexthop_address.bytes, 16); @@ -2880,6 +2883,7 @@ inline void cWorker::route_tunnel_nexthop(rte_mbuf* mbuf, metadata->transport_headerOffset = metadata->network_headerOffset + sizeof(rte_ipv6_hdr); } + if (!skip_udp_mpls) { rte_udp_hdr* udpHeader = rte_pktmbuf_mtod_offset(mbuf, rte_udp_hdr*, metadata->transport_headerOffset); @@ -2889,6 +2893,7 @@ inline void cWorker::route_tunnel_nexthop(rte_mbuf* mbuf, udpHeader->dgram_cksum = 0; } + if (!skip_udp_mpls) { uint32_t* mplsHeaderTransport = rte_pktmbuf_mtod_offset(mbuf, uint32_t*, metadata->transport_headerOffset + sizeof(rte_udp_hdr)); @@ -3265,7 +3270,7 @@ inline void cWorker::nat64stateful_lan_flow(rte_mbuf* mbuf, { route_entry(mbuf); } - else if (flow.type == common::globalBase::eFlowType::route_tunnel) + else if (flow.type == common::globalBase::eFlowType::route_tunnel || flow.type == common::globalBase::eFlowType::route_tunnel_ipip) { route_tunnel_entry(mbuf); } @@ -3424,7 +3429,7 @@ inline void cWorker::nat64stateful_wan_flow(rte_mbuf* mbuf, { route_entry(mbuf); } - else if (flow.type == common::globalBase::eFlowType::route_tunnel) + else if (flow.type == common::globalBase::eFlowType::route_tunnel || flow.type == common::globalBase::eFlowType::route_tunnel_ipip) { route_tunnel_entry(mbuf); } @@ -3504,7 +3509,7 @@ inline void cWorker::nat64stateless_ingress_flow(rte_mbuf* mbuf, { route_entry(mbuf); } - else if (flow.type == common::globalBase::eFlowType::route_tunnel) + else if (flow.type == common::globalBase::eFlowType::route_tunnel || flow.type == common::globalBase::eFlowType::route_tunnel_ipip) { route_tunnel_entry(mbuf); } @@ -3623,7 +3628,7 @@ inline void cWorker::nat64stateless_egress_flow(rte_mbuf* mbuf, { route_entry(mbuf); } - else if (flow.type == common::globalBase::eFlowType::route_tunnel) + else if (flow.type == common::globalBase::eFlowType::route_tunnel || flow.type == common::globalBase::eFlowType::route_tunnel_ipip) { route_tunnel_entry(mbuf); } @@ -3795,7 +3800,7 @@ inline void cWorker::nat46clat_lan_flow(rte_mbuf* mbuf, { route_entry(mbuf); } - else if (flow.type == common::globalBase::eFlowType::route_tunnel) + else if (flow.type == common::globalBase::eFlowType::route_tunnel || flow.type == common::globalBase::eFlowType::route_tunnel_ipip) { route_tunnel_entry(mbuf); } @@ -3874,7 +3879,7 @@ inline void cWorker::nat46clat_wan_flow(rte_mbuf* mbuf, { route_entry(mbuf); } - else if (flow.type == common::globalBase::eFlowType::route_tunnel) + else if (flow.type == common::globalBase::eFlowType::route_tunnel || flow.type == common::globalBase::eFlowType::route_tunnel_ipip) { route_tunnel_entry(mbuf); } @@ -5996,7 +6001,7 @@ YANET_NEVER_INLINE void cWorker::slowWorkerFlow(rte_mbuf* mbuf, { route_entry(mbuf); } - else if (flow.type == common::globalBase::eFlowType::route_tunnel) + else if (flow.type == common::globalBase::eFlowType::route_tunnel || flow.type == common::globalBase::eFlowType::route_tunnel_ipip) { route_tunnel_entry(mbuf); }