Как получить время обработки пакетов (packet_in, flow_match, output) в коммутаторе OVS?

Я пытаюсь оценить метод маршрутизации, реализованный мной с помощью Mininet, Open vSwitch и контроллера Ryu. Но в настоящее время я не могу понять методы измерения времени обработки пакетов в коммутаторе. Я могу измерить время обработки тестового сообщения, так как packet_in происходит для них и сообщает обратно программе контроллера. Но как измерить время обработки пакетов, о наличии которых коммутатор не сообщит контроллеру (packet_in не произойдет)? Вероятно, команда ovs-ofctl имеет некоторые параметры, которые могут сообщать мне время. Но все еще не уверен, как это сделать. Пожалуйста, помогите мне в этом случае. У меня недостаточно ресурсов в Интернете. Заранее спасибо за помощь.


person moyeen52    schedule 09.04.2018    source источник
comment
Не могли бы вы уточнить, что вы подразумеваете под packet processing time within switch? Вы имеете в виду время, которое требуется Open vSwitch в целом (путь данных + медленный путь) для обработки пакета? Вы хотите измерить это для каждого пакета или в среднем?   -  person pchaigno    schedule 09.04.2018
comment
Спасибо @pchaigno. Я хочу измерить каждый пакет. И мне интересно узнать время между packet_in и packet_out.   -  person moyeen52    schedule 10.04.2018
comment
Так это время обработки в контроллере? Почему бы не измерить его на контроллере (либо в самом контроллере, либо путем трассировки на уровне операционной системы)?   -  person pchaigno    schedule 10.04.2018
comment
Пакеты, которые я собираюсь отправить, не будут связываться с контроллером, поскольку в таблице потоков Open vSwitch есть правило соответствия. @pchaigno знаете ли вы, как измерить задержку внутри каждого OVS. или любая команда, которая может регистрировать время входа и выхода пакета? Спасибо большое за Ваш комментарий.   -  person moyeen52    schedule 10.04.2018
comment
Сообщение PACKET_IN не дойдет до контроллера?? Я больше не уверен, что следую за тобой...   -  person pchaigno    schedule 10.04.2018
comment
Никакое сообщение packet_in не достигнет контроллера, только если поток не соответствует таблице. Но для моего случая поток будет соответствовать записям таблицы. Таким образом, никакое сообщение не будет отправлено контроллеру. Это что-то про Open vSwitch. Думаю, может быть какой-то журнал, который отслеживает пакеты. Но спасибо @pchaigno за вашу помощь.   -  person moyeen52    schedule 11.04.2018
comment
О, так вы имеете в виду, что у вас есть сообщение PACKET_IN, проходящее через второй коммутатор, который соответствует ему? Было бы полезно, если бы вы могли подробно описать свою настройку (переключатели и таблицы потоков).   -  person pchaigno    schedule 11.04.2018
comment
Я сделал упреждающую настройку таблиц потоков (все правила переадресации добавлены изначально). Поскольку в таблице потоков коммутатора есть правило сопоставления, пакет, поступающий на интерфейс этого коммутатора, будет сопоставляться с таблицей потоков. Поскольку совпадение приводит к выходному порту, пакет будет выходить через этот порт. Поскольку нет промаха совпадения потока (поскольку пакет соответствует правилам внутри таблицы потоков), связи с контроллером не будет. Таким образом, событие package_in не будет запущено, и контроллер ничего не узнает об этом пакете. спасибо @pchaigno за ваш запрос.   -  person moyeen52    schedule 12.04.2018
comment
Тогда почему вы сказали И мне интересно узнать время между входящим и исходящим пакетами.?? Итак, вам нужно время между приемом пакета Open vSwitch и его передачей (или сбросом) на сетевую карту?   -  person pchaigno    schedule 12.04.2018
comment
да. извините за путаницу @pchaigno   -  person moyeen52    schedule 13.04.2018


Ответы (1)


Пока вы используете путь данных ядра Open vSwitch, вы должны иметь возможность получать данные о задержке обработки для каждого пакета с помощью обычных наборов инструментов трассировки Linux.

Ниже приведен пример использования инфраструктуры BPF (требуется Linux v4.4+) и инструментария bcc (I иметь версию 0.5.0-1). Учтите, однако, что при высокой скорости передачи пакетов накладные расходы, связанные с запуском этого инструмента, могут быть значительными. Еще один способ измерить накладные расходы, добавляемые вашими модификациями, — измерить максимальную пропускную способность, которую коммутатор может достичь с вашими модификациями и без них.

#!/usr/bin/env python
from bcc import BPF
import sys
import ctypes as ct

prog = """
#include <uapi/linux/ptrace.h>
#include <linux/openvswitch.h>

struct vport;

enum action_t {
    DROP = 0,
    OUTPUT,
};

struct proc_record_t {
    u64 delay;
    enum action_t action;
};

BPF_HASH(pkts, struct sk_buff *, u64, 1024);
BPF_PERF_OUTPUT(events);

// Take a timestamp at packet reception by Open vSwitch.
int
kprobe__ovs_vport_receive(struct pt_regs *ctx, struct vport *port, struct sk_buff *skb) {
    u64 ts = bpf_ktime_get_ns();
    pkts.update(&skb, &ts);
    return 0;
}

// Once the packet has been processed by the switch, measure the processing delay and send to userspace using perf_submit.
static inline void
end_processing(struct pt_regs *ctx, struct sk_buff *skb, enum action_t action) {
    u64 *tsp = pkts.lookup(&skb);
    if (tsp) {
        u64 ts = bpf_ktime_get_ns();
        struct proc_record_t record = {};
        record.delay = ts - *tsp;
        record.action = action;
        events.perf_submit(ctx, &record, sizeof(record));
        pkts.delete(&skb);
    }
}

// Called when packets are dropped by Open vSwitch.
int
kprobe__consume_skb(struct pt_regs *ctx, struct sk_buff *skb) {
    end_processing(ctx, skb, DROP);
    return 0;
}

// Called when packets are outputted by Open vSwitch.
int
kprobe__ovs_vport_send(struct pt_regs *ctx, struct vport *vport, struct sk_buff *skb) {
    end_processing(ctx, skb, OUTPUT);
    return 0;
}
"""

b = BPF(text=prog)

class Data(ct.Structure):
    _fields_ = [("delay", ct.c_ulonglong),
                ("action", ct.c_int)]
actions = ["drop", "output"]

print("%-18s %s" % ("DELAY(ns)", "ACTION"))

# Callback function to display information from kernel
def print_event(cpu, data, size):
    event = ct.cast(data, ct.POINTER(Data)).contents
    print("%-18d %s" % (event.delay, actions[event.action]))

b["events"].open_perf_buffer(print_event)
while True:
    b.kprobe_poll()

Вам потребуется установить bcc для выполнения этого скрипта. Тогда это так же просто, как:

$ sudo python trace_processing_time.py
DELAY(ns)          ACTION
97385              drop
55630              drop
38768              drop
61113              drop
10382              output
14795              output

См. документацию bcc, чтобы узнать, как работает этот сценарий. Вам нужно будет изменить его, если вы хотите поддерживать больше действий OpenFlow (в настоящее время только drop и output).

person pchaigno    schedule 15.04.2018
comment
Большое спасибо. Я сделаю дальнейшую модификацию вашей программы. Но большое спасибо за ваше драгоценное время. - person moyeen52; 18.04.2018