重大なキューの大幅で持続的なドロップは、容量超過の状況における一般的な現象であり、ユーザーに影響を与える可能性があります。

次の重大なキューのカウンタは、注意深く監視する必要があります。

[vc_queue_net_sch、vc_queue_link_select、vc_queue_link_sch]:これらのスケジューラは、Edge に送信されるパケットのリンクの選択、QoS、リンクのスケジュール設定を目的としています。Orchestrator は、グローバル パケット スケジューラ (vc_queue_net_sch) からパケットを取得し、送信するための適切なリンク (vc_queue_link_select) を選択し、リンクレベルのパケット スケジューラ (vc_queue_link_sch) のキューに登録します。

ここでのドロップは、Gateway が VCMP トラフィック(たとえば、インターネットからの戻りパケット)を Edge に十分な速度で送信できないことを示しています。

[vc_queue_link_encrypt_0、vc_queue_link_encrypt_1]:これはソフトウェアベースのパケット暗号化であり、パケット暗号化の他に、カプセル化、およびパケット送信前の同様の処理を管理します。

DPDK 対応の Gateway では、容量の問題は、まずこのキューのドロップとして観察されます。キュー内のドロップは、Gateway がトラフィックを十分な速度で暗号化できないことを示しています。

[vc_queue_vcmp_tx]:これは VCMP パケットのパケット転送です。キューでは、インターフェイスでのパケットの送信、必要な再送信のためのキューイング、およびパケットの解放を処理します。キュー内のドロップは、Gateway が VCMP トラフィック(たとえば、インターネットからの戻りパケット)を Edge に十分な速度で送信できないことを示しています。

以下は、vcmp_tx ドロップを確認するためのサンプルの Python スクリプトです。キューにドロップがある Gateway で Python スクリプトを実行して、問題の詳細を表示します。

#!/usr/bin/env python
"""
Check VCG vcmp handoff drops packet check
"""
import os
import sys
import subprocess
import commands
import re
import json
from optparse import OptionParser

# Parse commandline options:
parser = OptionParser(usage="%prog -w <warning threshold> -c <critical threshold> [ -h ]")
parser.add_option("-w", "--warning", action="store", type="string", dest="warn_threshold", help="Count Warning threshold should be in <value>")
parser.add_option("-c", "--critical",action="store", type="string", dest="crit_threshold", help="Count Critical threshold should be in <value>")
(options, args) = parser.parse_args()

json_data= {"vcg_handoff_data": {"count":0,"drops":[]}}
vcg_handoff_file="/tmp/vcg_handoff_drop_check"
bw_threshold=768000

def find_bw_throughput():
    total_bw = 0
    value = 2
    flag = os.path.exists("/opt/vc/etc/dpdk-override.json")
    if flag is True:
       with open("/opt/vc/etc/dpdk-override.json") as json_file:
            data = json.load(json_file)
       value = data["enabled"]
    if value == 0:
      status,output = commands.getstatusoutput("ifstat  -bqTn 1 1")
      if status == 0:
         total_bw = float(output.splitlines()[-1].split()[-1]) + float(output.splitlines()[-1].split()[-2])
    return int(total_bw)

def store_vcg_hanoff_queue_qlength():
    samples_count = 5
    if not os.path.isfile(vcg_handoff_file):
       with open(vcg_handoff_file, 'w') as outfile:
           json.dump(json_data, outfile )

    if os.path.isfile(vcg_handoff_file):
       with open(vcg_handoff_file) as vcg_handoff_data:
           handoff_data = json.load(vcg_handoff_data)
    else:
       with open(vcg_handoff_file, 'w') as outfile:
           json.dump(json_data, outfile )

    if os.path.isfile('/opt/vc/bin/debug.py'):
       L=[]
       f=subprocess.check_output(["/opt/vc/bin/debug.py","--handoff"])
       x=[r.split() for r in f.split('\n')]
       res = list(filter(None, x))

       if handoff_data["vcg_handoff_data"]["count"] == 0:
           for item in res:
              if not item[0] == "name":
                 #handoff_data["vcg_handoff_data"]["drops"].append({item[0]:[item[13]]})
                 handoff_data["vcg_handoff_data"]["drops"].append({item[0]:["1"] * samples_count})
                 handoff_data["vcg_handoff_data"]["count"] = 1
           with open(vcg_handoff_file, 'w') as outfile:
                json.dump(handoff_data, outfile )

       if not handoff_data["vcg_handoff_data"]["count"] == 0:
        count_status = handoff_data["vcg_handoff_data"]["count"] - 1
        for item in res:
            if not item[0] == "name":
               for key in  handoff_data["vcg_handoff_data"]["drops"]:
                   field_num = len(item) - 6
                   if item[0] == key.keys()[0]:
                      key[key.keys()[0]].append(item[field_num])
                      del key[key.keys()[0]][0]
                      #key[key.keys()[0]][count_status]=item[field_num]
        handoff_data["vcg_handoff_data"]["count"] += 1
        if handoff_data["vcg_handoff_data"]["count"] == samples_count + 1:
           handoff_data["vcg_handoff_data"]["count"] = 1

        with open(vcg_handoff_file, 'w') as outfile:
           json.dump(handoff_data, outfile )

def get_status_of_drops(warn_value,crit_value):
    result = []
    diff_drops_data = []
    both_value = False
    total_bw = find_bw_throughput()
    if os.path.isfile(vcg_handoff_file):
       with open(vcg_handoff_file) as vcg_handoff_data:
           handoff_data = json.load(vcg_handoff_data)

    for drops in handoff_data["vcg_handoff_data"]["drops"]:
       for key,value in drops.items():
           if key == "vc_queue_vcmp_tx_0":
               for cumlative_data in range(len(value)):
                  if not cumlative_data == 4:
                     drop_value = int(value[cumlative_data+1]) - int(value[cumlative_data])
                     diff_drops_data.append(drop_value)
                     warn_counter = 0
                     crit_counter = 0
                     for data in diff_drops_data:
                        if int(data) >= int(crit_value) and int(total_bw) > int(bw_threshold):
                           both_value = True
                        if int(data) > int(crit_value):
                          crit_counter +=1
                        if int(data) > int(warn_value) and  int(data) < int(crit_value):
                          warn_counter +=1
                     if both_value == True:
                        if not result:
                           result.append({key:diff_drops_data,"current_bw":total_bw,"status":"critical"})
                     if crit_counter  == 4:
                        result.append({key:diff_drops_data,"current_bw":total_bw,"status":"critical"})
                     if warn_counter == 4:
                        result.append({key:diff_drops_data,"status":"warning"})
    if not result:
       return "OK",diff_drops_data,total_bw
    else:
       return result

if __name__ == '__main__':

   crit_threshold = options.crit_threshold
   warn_threshold = options.warn_threshold
   crit = 0
   if not options.crit_threshold:
      print "CRITICAL: Missing critical threshold value."
      sys.exit(2)
   if not options.warn_threshold:
      print "CRITICAL: Missing warning threshold value."
      sys.exit(2)

   store_vcg_hanoff_queue_qlength()
   result = get_status_of_drops(warn_threshold,crit_threshold)
   result_type = isinstance(result, tuple)
   if result_type != True:
      for item in result:
         if item["status"] == "critical":
            crit = 1

   if result[0] == "OK":
      print "OK: Handoff drops with 5 samples are good and Current drop values %s and Current BW is %s Kbps" %(result[1],result[2])
      sys.exit(0)
   elif crit == 1:
      print "Critical: List of drops which are above %s packets: %s. Current_bw value is in kbps" %(crit_threshold, result)
      sys.exit(2)
   else:
      print "Warning: List of drops which are above %s packets: %s. Current_bw value is in kbps" %(warn_threshold,result)
      sys.exit(1)

[vc_queue_vcmp_data_0、vc_queue_vcmp_data_1]:これは、VCMP トンネルを介して受信した VCMP データ パケットの処理の最初のステージです。キューはパケットの並べ替えと見つからないパケットを処理します。これは、VCMP トンネルを介して送信されるデータ パケットの処理の開始です。

キュー内のドロップは、Gateway が Edge から十分な速度でトラフィックを受信できないことを示しています。これは、Gateway でのパケット損失を間接的に示している可能性があり、パケットの大幅な並べ替えが必要です。

[vc_queue_natt_0、vc_queue_natt_1、vc_queue_esp_0、vc_queue_esp_1]:これは NATT/ESP で暗号化されたトラフィックの復号化です。暗号化されたトンネルを介して到着したトラフィックは、復号化に必要な状態を設定するためにここに送られ、復号化処理のキューに渡されます。

キュー内のドロップは、Gateway が Non SD-WAN Destination トラフィックを十分な速度で復号化できないことを示しています。

[ipv4_bh]:これは、NAT トラフィックの場合はインターネットから、VLAN/VRF トラフィックの場合は PE ルーターから受信した戻りパケットに対する、ルーティング、QoS、フロー、ピアの関連付けなどの IPv4 データ パケット処理です。

DPDK 対応でない Gateway を除くすべての Gateway では、容量の問題は、まずキューのドロップとして観察されます。キュー内のドロップは、Gateway がパケットを十分な速度で受信できないことを示しています。