@@ -32,7 +32,7 @@ const std::string PARAMETER_MAC = "MAC";
3232const std::string PARAMETER_IP = " IP" ;
3333const std::string PARAMETER_PEER = " PEER" ;
3434
35- std::set <std::string> ExtIface::used_ifaces;
35+ std::map <std::string, ExtIface* > ExtIface::used_ifaces;
3636
3737ExtIface::ExtIface (const std::string &iface)
3838 : PeerIface(iface_mutex_),
@@ -43,7 +43,7 @@ ExtIface::ExtIface(const std::string &iface)
4343 throw std::runtime_error (" Iface already in use" );
4444 }
4545
46- used_ifaces.insert (iface);
46+ used_ifaces.insert ({ iface, this } );
4747
4848 // Save the ifindex
4949 ifindex_iface = if_nametoindex (iface.c_str ());
@@ -60,6 +60,14 @@ ExtIface::~ExtIface() {
6060 used_ifaces.erase (iface_);
6161}
6262
63+ ExtIface* ExtIface::get_extiface (const std::string &iface_name) {
64+ if (used_ifaces.count (iface_name) == 0 ) {
65+ return NULL ;
66+ }
67+
68+ return used_ifaces[iface_name];
69+ }
70+
6371uint16_t ExtIface::get_index () const {
6472 return index_;
6573}
@@ -172,39 +180,82 @@ void ExtIface::set_next(uint16_t next, ProgramType type) {
172180 }
173181}
174182
183+ TransparentCube* ExtIface::get_next_cube (ProgramType type) {
184+ auto next = get_next (type);
185+ for (auto &it : cubes_) {
186+ if (it->get_index (type) == next) {
187+ return it;
188+ }
189+ }
190+ return NULL ;
191+ }
192+
193+ uint16_t ExtIface::get_next (ProgramType type) {
194+ int zero = 0 ;
195+ unsigned int value = 0 ;
196+ auto program = (type == ProgramType::INGRESS) ? &ingress_program_ : &egress_program_;
197+ auto index_map = program->get_array_table <uint32_t >(" index_map" );
198+ auto st = index_map.get_value (zero, value);
199+ if (st.code () == -1 ) {
200+ logger->error (" failed to get interface {0} nexthop" , get_iface_name ());
201+ }
202+
203+ return value & 0xffff ;
204+ }
205+
206+ std::vector<std::string> ExtIface::get_service_chain (ProgramType type) {
207+ std::vector<std::string> chain;
208+ TransparentCube *cube;
209+ auto nh = get_next (type);
210+
211+ while (nh != 0xffff ) {
212+ cube = NULL ;
213+ for (auto c : cubes_) {
214+ if (c->get_index (type) == nh) {
215+ cube = c;
216+ break ;
217+ }
218+ }
219+ chain.push_back (cube ? cube->get_name () : " unknown" );
220+ nh = cube->get_next (type);
221+ }
222+ chain.push_back (nh==0xffff ? " stack" : " unknown" );
223+
224+ return chain;
225+ }
226+
175227void ExtIface::update_indexes () {
176228 int i;
177229
178230 // TODO: could we avoid to recalculate in case there is not peer?
179231
180- std::vector<uint16_t > ingress_indexes (cubes_.size ()) ;
181- std::vector<uint16_t > egress_indexes (cubes_.size ());
232+ std::vector<uint16_t > ingress_indexes (cubes_.size (), 0xffff ) ;
233+ std::vector<uint16_t > egress_indexes (cubes_.size (), 0xffff );
182234
183235 for (i = 0 ; i < cubes_.size (); i++) {
184236 ingress_indexes[i] = cubes_[i]->get_index (ProgramType::INGRESS);
185237 egress_indexes[i] = cubes_[i]->get_index (ProgramType::EGRESS);
186238 }
187239
188- // ingress chain: NIC -> cube[N-1 ] -> ... -> cube[0 ] -> stack (or peer)
240+ // ingress chain: NIC -> cube[0 ] -> ... -> cube[n-1 ] -> stack (or peer)
189241 // CASE2: cube[0] -> stack (or)
190- for (i = 0 ; i < cubes_.size (); i++ ) {
191- if (ingress_indexes[i]) {
242+ for (i = cubes_.size () - 1 ; i >= 0 ; i-- ) {
243+ if (ingress_indexes[i] != 0xffff ) {
192244 cubes_[i]->set_next (peer_ ? peer_->get_index () : 0xffff ,
193245 ProgramType::INGRESS);
194246 break ;
195247 }
196248 }
197249
198- // cube[N-1] -> ... -> cube[0]
199- for (int j = i + 1 ; j < cubes_.size (); j++) {
200- if (ingress_indexes[j]) {
250+ for (int j = i - 1 ; j >= 0 ; j--) {
251+ if (ingress_indexes[j] != 0xffff ) {
201252 cubes_[j]->set_next (ingress_indexes[i], ProgramType::INGRESS);
202253 i = j;
203254 }
204255 }
205256
206257 // CASE4: NIC -> cube[N-1] or peer
207- if (i < cubes_. size () && ingress_indexes[i]) {
258+ if (i >= 0 && ingress_indexes[i] != 0xffff ) {
208259 set_next (ingress_indexes[i], ProgramType::INGRESS);
209260 } else {
210261 set_next (peer_ ? peer_->get_index () : 0 , ProgramType::INGRESS);
@@ -214,7 +265,7 @@ void ExtIface::update_indexes() {
214265
215266 // cube[0] -> "egress"
216267 for (i = 0 ; i < cubes_.size (); i++) {
217- if (egress_indexes[i]) {
268+ if (egress_indexes[i] != 0xffff ) {
218269 cubes_[i]->set_next (0xffff , ProgramType::EGRESS);
219270 break ;
220271 }
@@ -227,14 +278,14 @@ void ExtIface::update_indexes() {
227278
228279 // cubes[N-1] -> ... -> cube[0]
229280 for (int j = i + 1 ; j < cubes_.size (); j++) {
230- if (egress_indexes[j]) {
281+ if (egress_indexes[j] != 0xffff ) {
231282 cubes_[j]->set_next (egress_indexes[i], ProgramType::EGRESS);
232283 i = j;
233284 }
234285 }
235286
236287 // "nic" -> cubes[N-1] or peer
237- if (i < cubes_.size () && egress_indexes[i]) {
288+ if (i < cubes_.size () && egress_indexes[i] != 0xffff ) {
238289 set_next (egress_indexes[i], ProgramType::EGRESS);
239290 } else {
240291 Port *peer_port = dynamic_cast <Port *>(peer_);
@@ -243,12 +294,6 @@ void ExtIface::update_indexes() {
243294 }
244295}
245296
246- // in external ifaces the cubes must be allocated in the inverse order.
247- // first is the one that hits ingress traffic.
248- int ExtIface::calculate_cube_index (int index) {
249- return 0 - index;
250- }
251-
252297bool ExtIface::is_used () const {
253298 std::lock_guard<std::mutex> guard (iface_mutex_);
254299 return cubes_.size () > 0 || peer_ != nullptr ;
0 commit comments