@@ -180,39 +180,82 @@ void ExtIface::set_next(uint16_t next, ProgramType type) {
180180 }
181181}
182182
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+
183227void ExtIface::update_indexes () {
184228 int i;
185229
186230 // TODO: could we avoid to recalculate in case there is not peer?
187231
188- std::vector<uint16_t > ingress_indexes (cubes_.size ()) ;
189- 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 );
190234
191235 for (i = 0 ; i < cubes_.size (); i++) {
192236 ingress_indexes[i] = cubes_[i]->get_index (ProgramType::INGRESS);
193237 egress_indexes[i] = cubes_[i]->get_index (ProgramType::EGRESS);
194238 }
195239
196- // ingress chain: NIC -> cube[N-1 ] -> ... -> cube[0 ] -> stack (or peer)
240+ // ingress chain: NIC -> cube[0 ] -> ... -> cube[n-1 ] -> stack (or peer)
197241 // CASE2: cube[0] -> stack (or)
198- for (i = 0 ; i < cubes_.size (); i++ ) {
199- if (ingress_indexes[i]) {
242+ for (i = cubes_.size () - 1 ; i >= 0 ; i-- ) {
243+ if (ingress_indexes[i] != 0xffff ) {
200244 cubes_[i]->set_next (peer_ ? peer_->get_index () : 0xffff ,
201245 ProgramType::INGRESS);
202246 break ;
203247 }
204248 }
205249
206- // cube[N-1] -> ... -> cube[0]
207- for (int j = i + 1 ; j < cubes_.size (); j++) {
208- if (ingress_indexes[j]) {
250+ for (int j = i - 1 ; j >= 0 ; j--) {
251+ if (ingress_indexes[j] != 0xffff ) {
209252 cubes_[j]->set_next (ingress_indexes[i], ProgramType::INGRESS);
210253 i = j;
211254 }
212255 }
213256
214257 // CASE4: NIC -> cube[N-1] or peer
215- if (i < cubes_. size () && ingress_indexes[i]) {
258+ if (i >= 0 && ingress_indexes[i] != 0xffff ) {
216259 set_next (ingress_indexes[i], ProgramType::INGRESS);
217260 } else {
218261 set_next (peer_ ? peer_->get_index () : 0 , ProgramType::INGRESS);
@@ -222,7 +265,7 @@ void ExtIface::update_indexes() {
222265
223266 // cube[0] -> "egress"
224267 for (i = 0 ; i < cubes_.size (); i++) {
225- if (egress_indexes[i]) {
268+ if (egress_indexes[i] != 0xffff ) {
226269 cubes_[i]->set_next (0xffff , ProgramType::EGRESS);
227270 break ;
228271 }
@@ -235,14 +278,14 @@ void ExtIface::update_indexes() {
235278
236279 // cubes[N-1] -> ... -> cube[0]
237280 for (int j = i + 1 ; j < cubes_.size (); j++) {
238- if (egress_indexes[j]) {
281+ if (egress_indexes[j] != 0xffff ) {
239282 cubes_[j]->set_next (egress_indexes[i], ProgramType::EGRESS);
240283 i = j;
241284 }
242285 }
243286
244287 // "nic" -> cubes[N-1] or peer
245- if (i < cubes_.size () && egress_indexes[i]) {
288+ if (i < cubes_.size () && egress_indexes[i] != 0xffff ) {
246289 set_next (egress_indexes[i], ProgramType::EGRESS);
247290 } else {
248291 Port *peer_port = dynamic_cast <Port *>(peer_);
0 commit comments