docs: def _build_ip_constraints(roles, ips, constraints):
      """Generate the constraints at the ip/device level.
      Those constraints are those used by ansible to enforce tc/netem rules.
      """
      local_ips = copy.deepcopy(ips)
      for constraint in constraints:
          gsrc = constraint['src']
          gdst = constraint['dst']
          gdelay = constraint['delay']
          grate = constraint['rate']
          gloss = constraint['loss']
          for s in roles[gsrc]:
              # one possible source
              # Get all the active devices for this source
              active_devices = filter(lambda x: x["active"],
                                      local_ips[s.alias]['devices'])
              # Get only the devices specified in the network constraint
              if 'network' in constraint:
                  active_devices = filter(
                      lambda x:
                      x['device'] == s.extra[constraint['network']],
                      active_devices)
              # Get only the name of the active devices
              sdevices = map(lambda x: x['device'], active_devices)
              for sdevice in sdevices:
                  # one possible device
                  for d in roles[gdst]:
                      # one possible destination
                      dallips = local_ips[d.alias]['all_ipv4_addresses']
                      # Let's keep docker bridge out of this
                      dallips = filter(lambda x: x != '172.17.0.1', dallips)
                      for dip in dallips:
                          local_ips[s.alias].setdefault('tc', []).append({
                              'source': s.alias,
                              'target': dip,
                              'device': sdevice,
                              'delay': gdelay,
                              'rate': grate,
                              'loss': gloss
                          })
      return local_ips