Я пытаюсь оценить метод маршрутизации, реализованный мной с помощью Mininet, Open vSwitch и контроллера Ryu. Но в настоящее время я не могу понять методы измерения времени обработки пакетов в коммутаторе. Я могу измерить время обработки тестового сообщения, так как packet_in
происходит для них и сообщает обратно программе контроллера. Но как измерить время обработки пакетов, о наличии которых коммутатор не сообщит контроллеру (packet_in
не произойдет)? Вероятно, команда ovs-ofctl
имеет некоторые параметры, которые могут сообщать мне время. Но все еще не уверен, как это сделать. Пожалуйста, помогите мне в этом случае. У меня недостаточно ресурсов в Интернете. Заранее спасибо за помощь.
Как получить время обработки пакетов (packet_in, flow_match, output) в коммутаторе OVS?
Ответы (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
).
packet processing time within switch
? Вы имеете в виду время, которое требуется Open vSwitch в целом (путь данных + медленный путь) для обработки пакета? Вы хотите измерить это для каждого пакета или в среднем? - person pchaigno   schedule 09.04.2018