src/Retic.cc
void Of13Backend::install(
    oxm::field_set match,
    std::vector<oxm::field_set> actions,
    uint16_t prio,
    retic::FlowSettings flow_settings
) {
    if (flow_settings.hard_timeout == retic::duration::zero()) {
        // there is no need to install its flow, becouse timeouts is zero
        return;
    }
    static const auto ofb_switch_id = oxm::switch_id();
    static const auto ofb_route_id = oxm::route();
    std::vector<retic::route_t> routes;
    std::map<uint64_t, oxm::field_set> rt_act;
    
    for(uint64_t i = 0; i < actions.size(); i++){
        auto route_id_it = actions[i].find(oxm::type(ofb_route_id));//get route id also
        if (route_id_it != match.end()) {
            Packet& pkt_iface(match);
            uint64_t rt_id = pkt_iface.load(ofb_route_id);
            actions[i].erase(oxm::mask<>(ofb_route_id));
            auto cur_route = retic::route_ids[rt_id];
            routes.push_back(cur_route);
            if(cur_route.first.type == 2 && !cur_route.second.empty()){
                match.modify(oxm::field<>(cur_route.first.sw_id));
                oxm::field_set tmp;
                tmp.modify(oxm::field<>(cur_route.first.outport));
                rt_act[rt_id] = actions[i];

                actions[i] = tmp;
            }else{
                actions[i].modify(oxm::field<>(cur_route.first.outport));
            }
            //first dpid actions changed if route
            //first switch in route
                //match get more from route
                //actions create from route
            //middle route switches
                //match get more from route
                //actions create from route
            //last switch in route
                //match get more from route
                //actions create from route
        }
    }
    auto switch_id_it = match.find(oxm::type(ofb_switch_id));
    if (switch_id_it != match.end()) {
        Packet& pkt_iface(match);
        uint64_t dpid = pkt_iface.load(ofb_switch_id);
        match.erase(oxm::mask<>(ofb_switch_id));
        install_on(dpid, match, actions, prio, flow_settings);
    } else {
        for (auto [dpid, driver]: m_drivers) {
            install_on(dpid, match, actions, prio, flow_settings);
        }
    }
    if(!rt_act.empty()){
        for(auto it : rt_act){
            auto rtt = retic::route_ids[it.first];
            for(uint64_t it2 = 0; it2 < rtt.second.size()-1; it2++){
                auto sw = rtt.second[it2].sw_id;
                auto inport = rtt.second[it2].inport;
                auto outport = rtt.second[it2].outport;
                match.modify(oxm::field<>(sw));
                match.modify(oxm::field<>(inport));
                oxm::field_set tm;
                tm.modify(oxm::field<>(outport));
                std::vector<oxm::field_set> t;
                t.push_back(tm);
                Packet& pkt_inface(match);
                uint64_t dpid = pkt_inface.load(ofb_switch_id);
                match.erase(oxm::mask<>(ofb_switch_id));
                uint16_t p = PRIO_HIGH;
                install_on(dpid, match, t, p, flow_settings);

            }
            auto sw = rtt.second[rtt.second.size()-1].sw_id;
            auto inport = rtt.second[rtt.second.size()-1].inport;
            auto outport = rtt.second[rtt.second.size()-1].outport;
            match.modify(oxm::field<>(sw));
            match.modify(oxm::field<>(inport));
            it.second.modify(oxm::field<>(outport));
            Packet& pkt_inface(match);
            uint64_t dpid = pkt_inface.load(ofb_switch_id);
            match.erase(oxm::mask<>(ofb_switch_id));
            uint16_t k = PRIO_HIGH;
            install_on(dpid, match, std::vector<oxm::field_set>{it.second}, k, flow_settings);

        }
    }
}
// TODO: remove code duplication of switch detection in install and installBarrier method
remove code duplication of switch detection in install and installBarrier method
remove code duplication of switch detection in install and installBarrier method
void Of13Backend::install(
    oxm::field_set match,
    std::vector<oxm::field_set> actions,
    uint16_t prio,
    retic::FlowSettings flow_settings
) {
    if (flow_settings.hard_timeout == retic::duration::zero()) {
        return;
    }
    static const auto ofb_switch_id = oxm::switch_id();
    static const auto ofb_route_id = oxm::route();
    std::vector<retic::route_t> routes;
    std::map<uint64_t, oxm::field_set> rt_act;
    for(uint64_t i = 0; i < actions.size(); i++){
        auto route_id_it = actions[i].find(oxm::type(ofb_route_id));
        if (route_id_it != match.end()) {
            Packet& pkt_iface(match);
            uint64_t rt_id = pkt_iface.load(ofb_route_id);
            actions[i].erase(oxm::mask<>(ofb_route_id));
            auto cur_route = retic::route_ids[rt_id];
            routes.push_back(cur_route);
            if(cur_route.first.type == 2 && !cur_route.second.empty()){
                match.modify(oxm::field<>(cur_route.first.sw_id));
                oxm::field_set tmp;
                tmp.modify(oxm::field<>(cur_route.first.outport));
                rt_act[rt_id] = actions[i];
                actions[i] = tmp;
            }else{
                actions[i].modify(oxm::field<>(cur_route.first.outport));
            }
        }
    }
    auto switch_id_it = match.find(oxm::type(ofb_switch_id));
    if (switch_id_it != match.end()) {
        Packet& pkt_iface(match);
        uint64_t dpid = pkt_iface.load(ofb_switch_id);
        match.erase(oxm::mask<>(ofb_switch_id));
        install_on(dpid, match, actions, prio, flow_settings);
    } else {
        for (auto [dpid, driver]: m_drivers) {
            install_on(dpid, match, actions, prio, flow_settings);
        }
    }
    if(!rt_act.empty()){
        for(auto it : rt_act){
            auto rtt = retic::route_ids[it.first];
            for(uint64_t it2 = 0; it2 < rtt.second.size()-1; it2++){
                auto sw = rtt.second[it2].sw_id;
                auto inport = rtt.second[it2].inport;
                auto outport = rtt.second[it2].outport;
                match.modify(oxm::field<>(sw));
                match.modify(oxm::field<>(inport));
                oxm::field_set tm;
                tm.modify(oxm::field<>(outport));
                std::vector<oxm::field_set> t;
                t.push_back(tm);
                Packet& pkt_inface(match);
                uint64_t dpid = pkt_inface.load(ofb_switch_id);
                match.erase(oxm::mask<>(ofb_switch_id));
                uint16_t p = PRIO_HIGH;
                install_on(dpid, match, t, p, flow_settings);
            }
            auto sw = rtt.second[rtt.second.size()-1].sw_id;
            auto inport = rtt.second[rtt.second.size()-1].inport;
            auto outport = rtt.second[rtt.second.size()-1].outport;
            match.modify(oxm::field<>(sw));
            match.modify(oxm::field<>(inport));
            it.second.modify(oxm::field<>(outport));
            Packet& pkt_inface(match);
            uint64_t dpid = pkt_inface.load(ofb_switch_id);
            match.erase(oxm::mask<>(ofb_switch_id));
            uint16_t k = PRIO_HIGH;
            install_on(dpid, match, std::vector<oxm::field_set>{it.second}, k, flow_settings);
        }
    }
}
void Of13Backend :: install ( oxm :: field_set match , std :: vector < oxm :: field_set > actions , uint16_t prio , retic :: FlowSettings flow_settings ) { if ( flow_settings . hard_timeout == retic :: duration :: zero ( ) ) { return ; } static const auto ofb_switch_id = oxm :: switch_id ( ) ; static const auto ofb_route_id = oxm :: route ( ) ; std :: vector < retic :: route_t > routes ; std :: map < uint64_t , oxm :: field_set > rt_act ; for ( uint64_t i = 0 ; i < actions . size ( ) ; i ++ ) { auto route_id_it = actions [ i ] . find ( oxm :: type ( ofb_route_id ) ) ; if ( route_id_it != match . end ( ) ) { Packet & pkt_iface ( match ) ; uint64_t rt_id = pkt_iface . load ( ofb_route_id ) ; actions [ i ] . erase ( oxm :: mask < > ( ofb_route_id ) ) ; auto cur_route = retic :: route_ids [ rt_id ] ; routes . push_back ( cur_route ) ; if ( cur_route . first . type == 2 && ! cur_route . second . empty ( ) ) { match . modify ( oxm :: field < > ( cur_route . first . sw_id ) ) ; oxm :: field_set tmp ; tmp . modify ( oxm :: field < > ( cur_route . first . outport ) ) ; rt_act [ rt_id ] = actions [ i ] ; actions [ i ] = tmp ; } else { actions [ i ] . modify ( oxm :: field < > ( cur_route . first . outport ) ) ; } } } auto switch_id_it = match . find ( oxm :: type ( ofb_switch_id ) ) ; if ( switch_id_it != match . end ( ) ) { Packet & pkt_iface ( match ) ; uint64_t dpid = pkt_iface . load ( ofb_switch_id ) ; match . erase ( oxm :: mask < > ( ofb_switch_id ) ) ; install_on ( dpid , match , actions , prio , flow_settings ) ; } else { for ( auto [ dpid , driver ] : m_drivers ) { install_on ( dpid , match , actions , prio , flow_settings ) ; } } if ( ! rt_act . empty ( ) ) { for ( auto it : rt_act ) { auto rtt = retic :: route_ids [ it . first ] ; for ( uint64_t it2 = 0 ; it2 < rtt . second . size ( ) - 1 ; it2 ++ ) { auto sw = rtt . second [ it2 ] . sw_id ; auto inport = rtt . second [ it2 ] . inport ; auto outport = rtt . second [ it2 ] . outport ; match . modify ( oxm :: field < > ( sw ) ) ; match . modify ( oxm :: field < > ( inport ) ) ; oxm :: field_set tm ; tm . modify ( oxm :: field < > ( outport ) ) ; std :: vector < oxm :: field_set > t ; t . push_back ( tm ) ; Packet & pkt_inface ( match ) ; uint64_t dpid = pkt_inface . load ( ofb_switch_id ) ; match . erase ( oxm :: mask < > ( ofb_switch_id ) ) ; uint16_t p = PRIO_HIGH ; install_on ( dpid , match , t , p , flow_settings ) ; } auto sw = rtt . second [ rtt . second . size ( ) - 1 ] . sw_id ; auto inport = rtt . second [ rtt . second . size ( ) - 1 ] . inport ; auto outport = rtt . second [ rtt . second . size ( ) - 1 ] . outport ; match . modify ( oxm :: field < > ( sw ) ) ; match . modify ( oxm :: field < > ( inport ) ) ; it . second . modify ( oxm :: field < > ( outport ) ) ; Packet & pkt_inface ( match ) ; uint64_t dpid = pkt_inface . load ( ofb_switch_id ) ; match . erase ( oxm :: mask < > ( ofb_switch_id ) ) ; uint16_t k = PRIO_HIGH ; install_on ( dpid , match , std :: vector < oxm :: field_set > { it . second } , k , flow_settings ) ; } } }
TODO: remove code duplication of switch detection in install and installBarrier method
TODO : remove code duplication of switch detection in install and installBarrier method
// there is no need to install its flow, becouse timeouts is zero //get route id also //first dpid actions changed if route //first switch in route //match get more from route //actions create from route //middle route switches //match get more from route //actions create from route //last switch in route //match get more from route //actions create from route