Сервис Point-to-Point (P2P) отвечает за построение туннеля между двумя выделенными точками на сети. Туннель определяется уникальным vlan тегом. На вход приложение принимает файл вида: vlan, <switch, port>:<switch,port>. При получении первого пакета с указанных портов с таким тегом нужно построить маршрут между этими двумя точками вида: in_port, vlan -> output (и туда, и обратно).
=> Из packet_in нужно достать vlan
Согласно файлу Packet.cc
// CONCEPT: ethaddr a = pkt.load(eth_src);
// eth_src (type) is implicitly convertible to oxm::mask<eth_src>
// with all bits set to 1
// oxm::field<> convertible to oxm::field<Type>
// with runtime check of size
// oxm::field<Type> convertible to Type::value_type
// with runtime check of mask (should be exact match)
// CONCEPT: oxm::field<ethaddr> m = pkt.load(eth_src & "ff:ff:00:00:00:00");
// oxm::mask<eth_src_meta> operator& (eth_src_meta, eth_src_meta::mask_type)
class VLANVid: public OXMTLV {
private:
uint16_t value_;
uint16_t mask_;
public:
VLANVid();
VLANVid(uint16_t value);
VLANVid(uint16_t value, uint16_t mask);
~VLANVid() {
}
virtual bool equals(const OXMTLV & other);
OXMTLV& operator=(const OXMTLV& field);
virtual VLANVid* clone() const {
return new VLANVid(*this);
}
size_t pack(uint8_t *buffer);
of_error unpack(uint8_t *buffer);
uint16_t value() const {
return this->value_;
}
uint16_t mask() const {
return this->mask_;
}
void value(uint16_t value) {
this->value_ = value;
}
void mask(uint16_t mask) {
this->mask_ = mask;
}
};
LOG(INFO) << "PacketIn captured";
ethaddr eth_dst = pkt.load(oxm::eth_dst());
auto vlan = pkt.load(oxm::vlan_vid());
uint16_t vlan_value = vlan;
[100%] Linking CXX executable ../runos
CMakeFiles/runos.dir/Homework.cc.o: In function `Homework::init(Loader*, std::map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, json11::Json, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, json11::Json> > > const&)::{lambda(std::shared_ptr<runos::SwitchConnection>)#1}::operator()(std::shared_ptr<runos::SwitchConnection>) const::{lambda(runos::Packet&, std::shared_ptr<runos::Flow>, runos::Decision)#1}::operator()(runos::Packet, runos::Flow, std::shared_ptr<runos::Flow>) const [clone .isra.250]':
Homework.cc:(.text+0x10d4): undefined reference to `unsigned short runos::bit_cast<unsigned short, runos::bits<12ul> >(runos::bits<12ul>)'
collect2: error: ld returned 1 exit status
src/CMakeFiles/runos.dir/build.make:864: recipe for target 'runos' failed
make[2]: *** [runos] Error 1
CMakeFiles/Makefile2:190: recipe for target 'src/CMakeFiles/runos.dir/all' failed
make[1]: *** [src/CMakeFiles/runos.dir/all] Error 2
Makefile:94: recipe for target 'all' failed
make: *** [all] Error 2
ERROR: Service 'runos' failed to build: The command '/bin/sh -c cd runos && third_party/bootstrap.sh && mkdir -p build; cd build && CXX=g++ cmake -DCMAKE_BUILD_TYPE=Release .. && make prefix -j2 && make -j2' returned a non-zero code: 2
Добавляем необходимую функцию в bits.hh
template<>
inline uint16_t bit_cast(const bits<12> from)
{ return from.to_ulong(); }
I1221 15:52:14.536087 10 Homework.cc:66] GOT PACKET IN
E1221 15:52:14.536741 10 Controller.cc:641] Unhandled exception: /root/runos/src/PacketParser.cc(327): Throw in function uint8_t* runos::PacketParser::access(runos::oxm::type) const
Dynamic exception type: boost::exception_detail::clone_impl<runos::out_of_range>
[tag_pi_handler*] = homework
[runos::tag_oxm_ns*] = 32768
[runos::tag_error_msg*] = Unsupported oxm field
[runos::tag_oxm_field*] = 6
[runos::maple::tag_trace*] = (T runos::oxm::eth_type{} == 1000100011001100 -> 0) (L runos::oxm::eth_src{} == 010010100111000110101011000010010110000111000011) (T runos::oxm::eth_type{} == 0000100000000000 -> 0) (T runos::oxm::eth_type{} == 0000100000000110 -> 0)
что это за runos::tag_oxm_field*] = 6
?
верно!
/* OXM Flow match field types for OpenFlow basic class. */
enum class basic_match_fields : uint8_t {
IN_PORT = 0, /* Switch input port. */
IN_PHY_PORT = 1, /* Switch physical input port. */
METADATA = 2, /* Metadata passed between tables. */
ETH_DST = 3, /* Ethernet destination address. */
ETH_SRC = 4, /* Ethernet source address. */
ETH_TYPE = 5, /* Ethernet frame type. */
VLAN_VID = 6, /* VLAN id. */
VLAN_PCP = 7, /* VLAN priority. */
IP_DSCP = 8, /* IP DSCP (6 bits in ToS field). */
IP_ECN = 9, /* IP ECN (2 bits in ToS field). */
IP_PROTO = 10, /* IP protocol. */
IPV4_SRC = 11, /* IPv4 source address. */
IPV4_DST = 12, /* IPv4 destination address. */
TCP_SRC = 13, /* TCP source port. */
TCP_DST = 14, /* TCP destination port. */
UDP_SRC = 15, /* UDP source port. */
UDP_DST = 16, /* UDP destination port. */
SCTP_SRC = 17, /* SCTP source port. */
SCTP_DST = 18, /* SCTP destination port. */
ICMPV4_TYPE = 19, /* ICMP type. */
ICMPV4_CODE = 20, /* ICMP code. */
ARP_OP = 21, /* ARP opcode. */
ARP_SPA = 22, /* ARP source IPv4 address. */
ARP_TPA = 23, /* ARP target IPv4 address. */
ARP_SHA = 24, /* ARP source hardware address. */
ARP_THA = 25, /* ARP target hardware address. */
IPV6_SRC = 26, /* IPv6 source address. */
IPV6_DST = 27, /* IPv6 destination address. */
IPV6_FLABEL = 28, /* IPv6 Flow Label */
ICMPV6_TYPE = 29, /* ICMPv6 type. */
ICMPV6_CODE = 30, /* ICMPv6 code. */
IPV6_ND_TARGET = 31, /* Target address for ND. */
IPV6_ND_SLL = 32, /* Source link-layer for ND. */
IPV6_ND_TLL = 33, /* Target link-layer for ND. */
MPLS_LABEL = 34, /* MPLS label. */
MPLS_TC = 35, /* MPLS TC. */
MPLS_BOS = 36, /* MPLS BoS bit. */
PBB_ISID = 37, /* PBB I-SID. */
TUNNEL_ID = 38, /* Logical Port Metadata. */
IPV6_EXTHDR = 39, /* IPv6 Extension Header pseudo-field */
};
if (eth->type == 0x8100){
if (sizeof(dot1q_hdr) <= data_len ){
dot1q = reinterpret_cast<dot1q_hdr*>(data);
bind({
{ ofb::ETH_TYPE, &dot1q->type },
{ ofb::ETH_SRC, &dot1q->src },
{ ofb::ETH_DST, &dot1q->dst },
{ ofb::VLAN_VID, &dot1q->tci } //fix this
});
type = dot1q->type;
len = dot1q->header_length();
}
}
PS аналогичное поведение наблюдается в версиях 0.6 (предложена для выполнения в задании) и 0.7