Skip to content

Commit a97d4b6

Browse files
authored
Merge pull request #85 from amorenoz/cookies
Extract cookie information from OVN
2 parents f5e439d + adda6cd commit a97d4b6

File tree

7 files changed

+383
-9
lines changed

7 files changed

+383
-9
lines changed

containers/k8s-ofparse/Dockerfile.dev

+64
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
FROM quay.io/fedora/fedora:33-x86_64 as builder
2+
3+
ARG OVN_REPO=https://github.com/ovn-org/ovn.git
4+
ARG OVN_BRANCH=main
5+
ARG OVS_REPO=https://github.com/openvswitch/ovs.git
6+
ARG OVS_BRANCH=master
7+
8+
RUN dnf upgrade -y && dnf install --best --refresh -y --setopt=tsflags=nodocs \
9+
python3-pyyaml python3-pip bind-utils procps-ng openssl numactl-libs firewalld-filesystem \
10+
libpcap hostname kubernetes-client python3-openvswitch python3-pyOpenSSL \
11+
iptables iproute jq iputils strace socat\
12+
@'Development Tools' rpm-build dnf-plugins-core kmod && \
13+
dnf clean all && rm -rf /var/cache/dnf/*
14+
15+
16+
WORKDIR /root
17+
RUN git clone $OVS_REPO
18+
19+
#Build OVS dependency
20+
WORKDIR /root/ovs
21+
RUN git fetch && git checkout $OVS_BRANCH && git log -n 1
22+
RUN sed -e 's/@VERSION@/0.0.1/' rhel/openvswitch-fedora.spec.in > /tmp/ovs.spec
23+
RUN dnf builddep /tmp/ovs.spec -y
24+
RUN rm -f /tmp/ovs.spec
25+
26+
#Build OVS binaries and install
27+
RUN echo "Building OVS rpm"
28+
RUN ./boot.sh
29+
RUN ./configure --prefix=/usr --localstatedir=/var --sysconfdir=/etc --enable-ssl
30+
RUN make rpm-fedora
31+
32+
#Clone OVN Source Code
33+
WORKDIR /root
34+
RUN git clone $OVN_REPO
35+
36+
#Build OVN binaries and install
37+
WORKDIR /root/ovn/
38+
RUN git fetch && git checkout $OVN_BRANCH && git log -n 1
39+
RUN ./boot.sh
40+
RUN ./configure --prefix=/usr --localstatedir=/var --sysconfdir=/etc --with-ovs-source=/root/ovs/
41+
RUN make rpm-fedora
42+
43+
44+
FROM quay.io/fedora/fedora:33-x86_64
45+
COPY --from=builder /root/ovn/rpm/rpmbuild/RPMS /root/ovn-rpmbuild
46+
COPY --from=builder /root/ovs/rpm/rpmbuild/RPMS /root/ovs-rpmbuild
47+
48+
RUN dnf upgrade -y && dnf install --best --refresh -y --setopt=tsflags=nodocs \
49+
python3-pyyaml python3-pip jq findutils grep git hostname kubernetes-client && \
50+
dnf clean all && rm -rf /var/cache/dnf/*
51+
52+
RUN find /root/ovs-rpmbuild -name "*.rpm" | grep -v src | xargs dnf install -y
53+
RUN find /root/ovn-rpmbuild -name "*.rpm" | grep -v src | xargs dnf install -y
54+
55+
# Install ovs-dbg
56+
ADD . /root/ovs-dbg
57+
WORKDIR /root/ovs-dbg
58+
RUN python3 -m pip install .
59+
60+
WORKDIR /root
61+
RUN rm -rf /root/ovs /root/ovn
62+
63+
ADD containers/k8s-ofparse/monitor.sh /root/
64+
ENTRYPOINT ["/root/monitor.sh"]

containers/k8s-ofparse/monitor.sh

+1-1
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ monitor() {
4040
#!/bin/bash
4141
4242
OFPARSE_ARGS="$ofparse_args"
43-
exec ofparse \$OFPARSE_ARGS \$@
43+
exec ofparse \$OFPARSE_ARGS "\$@"
4444
EOF
4545
chmod +x /usr/local/bin/k8s-ofparse
4646

docs/source/ofparse.rst

+50-2
Original file line numberDiff line numberDiff line change
@@ -151,13 +151,16 @@ Openflow parsing
151151

152152
The openflow flow parsing supports this extra formats:
153153

154-
**Logic**: To print the logical representation of a flow run:
154+
Logic format
155+
************
156+
157+
**logic**: To print the logical representation of a flow run:
155158

156159
::
157160

158161
ofparse openflow logic
159162

160-
(run `ofparse --help` for more details)
163+
(run `ofparse openflow logic --help` for more details)
161164

162165

163166
When printing a logical representation of a flow list, flows are grouped into *logical flows* that:
@@ -167,6 +170,50 @@ When printing a logical representation of a flow list, flows are grouped into *l
167170
- execute the same actions (regardless of the actions' arguments, except for resubmit and output)
168171
- Optionally, the *cookie* can be counted as part of the logical flow as well (*--cookie*)
169172

173+
Flows are sorted by table and then by logical flow:
174+
175+
176+
::
177+
178+
TABLE 1
179+
-> logial flow ( x n )
180+
-> flow 1
181+
-> flow 2
182+
...
183+
184+
185+
Cookie format
186+
*************
187+
Use **cookie** format to sort the flows by cookie and then by table
188+
189+
::
190+
191+
Cookie 0xa
192+
-> TABLE 1
193+
-> flow 1
194+
-> flow 2
195+
...
196+
-> TABLE 2
197+
...
198+
199+
200+
ovn-detrace integration
201+
***********************
202+
Both **cookie** and **logic** formats support integration with OVN, in particular with ovn-detrace
203+
utility.
204+
205+
You will need a recent OVN version that contains a specific `ovn-detrace patch`_ as well as locally
206+
accesible OVN Northbound and OVN Southbound ovsdb-server instances running.
207+
208+
If you have all that, you can enable ovn-detrace support and ofparse will use ovn-detrace to
209+
extract the OVN information for each cookie and print it alogside the Openflow flows.
210+
211+
See help for more information:
212+
213+
::
214+
215+
ofparse openflow cookie --help
216+
170217

171218
HTML representation
172219
*******************
@@ -349,3 +396,4 @@ Note filtering is typically applied before the range is calculated.
349396
.. _ovs-actions: http://www.openvswitch.org/support/dist-docs/ovs-actions.7.html
350397
.. _ovs-fields: http://www.openvswitch.org/support/dist-docs/ovs-fields.7.html
351398
.. _ovs-ofctl: http://www.openvswitch.org/support/dist-docs/ovs-ofctl.8.txt
399+
.. _`ovn-detrace patch`: https://github.com/ovn-org/ovn/commit/d659b6538b00bd72aeca1fc5dd3a3c337ac53f37

k8s/k8s-ofparse.yaml

+6-2
Original file line numberDiff line numberDiff line change
@@ -45,14 +45,18 @@ spec:
4545
path: /var/run/openvswitch
4646
containers:
4747
- name: k8s-ofparse
48-
image: quay.io/amorenoz/k8s-ofparse
48+
image: quay.io/amorenoz/k8s-ofparse-devel
4949
#imagePullPolicy: Always
5050
volumeMounts:
5151
- mountPath: /var/run/openvswitch/
5252
name: host-var-run-ovs
5353
env:
5454
- name: OVN_RUNDIR
5555
value: "/var/run/openvswitch"
56+
- name: OVN_NB_DB
57+
value: "unix:/var/run/openvswitch/ovnnb_db.sock"
58+
- name: OVN_SB_DB
59+
value: "unix:/var/run/openvswitch/ovnsb_db.sock"
5660
- name: OVS_RUNDIR
5761
value: "/var/run/openvswitch"
5862
command: ["/root/monitor.sh", "start"]
@@ -80,7 +84,7 @@ spec:
8084
path: /var/run/openvswitch
8185
containers:
8286
- name: k8s-ofparse
83-
image: quay.io/amorenoz/k8s-ofparse
87+
image: quay.io/amorenoz/k8s-ofparse-devel
8488
#imagePullPolicy: Always
8589
volumeMounts:
8690
- mountPath: /var/run/openvswitch/

ovs_dbg/odp.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,7 @@ def _action_decoders(cls):
196196
),
197197
"userdata": decode_default,
198198
"actions": decode_flag,
199-
"tunnel_out_port": decode_int,
199+
"tunnel_out_port": decode_default,
200200
"push_eth": nested_kv_decoder(
201201
KVDecoders(
202202
{

ovs_dbg/ofparse/ofp.py

+124-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import click
2+
import os
23

34
from ovs_dbg.ofp import OFPFlowFactory
4-
from ovs_dbg.ofparse.ofp_logic import LogicFlowProcessor
5+
from ovs_dbg.ofparse.ofp_logic import LogicFlowProcessor, CookieProcessor
56
from ovs_dbg.ofparse.main import maincli
67
from ovs_dbg.ofparse.process import (
78
FlowProcessor,
@@ -10,7 +11,6 @@
1011
)
1112
from ovs_dbg.ofparse.html import HTMLBuffer, HTMLFormatter, HTMLStyle
1213

13-
1414
factory = OFPFlowFactory()
1515

1616

@@ -49,7 +49,58 @@ def pretty(opts, heat_map):
4949
proc.print()
5050

5151

52+
def ovn_detrace_callback(ctx, param, value):
53+
"""click callback to add detrace information to config object and
54+
set general ovn-detrace flag to True
55+
"""
56+
ctx.obj[param.name] = value
57+
if value != param.default:
58+
ctx.obj["ovn_detrace_flag"] = True
59+
return value
60+
61+
5262
@openflow.command()
63+
@click.option(
64+
"-d",
65+
"--ovn-detrace",
66+
"ovn_detrace_flag",
67+
is_flag=True,
68+
show_default=True,
69+
help="Use ovn-detrace to extract cookie information (implies '-c')",
70+
)
71+
@click.option(
72+
"--ovn-detrace-path",
73+
default="/usr/bin",
74+
type=click.Path(),
75+
help="Use an alternative path to where ovn_detrace.py is located. "
76+
"Instead of using this option you can just set PYTHONPATH accordingly",
77+
show_default=True,
78+
callback=ovn_detrace_callback,
79+
)
80+
@click.option(
81+
"--ovnnb-db",
82+
default=os.getenv("OVN_NB_DB") or "unix:/var/run/ovn/ovnnb_db.sock",
83+
help="Specify the OVN NB database string (implies -d). "
84+
"If the OVN_NB_DB environment variable is set, it's used as default. "
85+
"Otherwise, the default is unix:/var/run/ovn/ovnnb_db.sock",
86+
callback=ovn_detrace_callback,
87+
)
88+
@click.option(
89+
"--ovnsb-db",
90+
default=os.getenv("OVN_SB_DB") or "unix:/var/run/ovn/ovnsb_db.sock",
91+
help="Specify the OVN NB database string (implies -d). "
92+
"If the OVN_NB_DB environment variable is set, it's used as default. "
93+
"Otherwise, the default is unix:/var/run/ovn/ovnnb_db.sock",
94+
callback=ovn_detrace_callback,
95+
)
96+
@click.option(
97+
"-o",
98+
"--ovn-filter",
99+
help="Specify a filter to be run on ovn-detrace information (implied -d). "
100+
"Format: python regular expression "
101+
"(see https://docs.python.org/3/library/re.html)",
102+
callback=ovn_detrace_callback,
103+
)
53104
@click.option(
54105
"-s",
55106
"--show-flows",
@@ -76,7 +127,17 @@ def pretty(opts, heat_map):
76127
help="Create heat-map with packet and byte counters (when -s is used)",
77128
)
78129
@click.pass_obj
79-
def logic(opts, show_flows, cookie_flag, heat_map):
130+
def logic(
131+
opts,
132+
ovn_detrace_flag,
133+
ovn_detrace_path,
134+
ovnnb_db,
135+
ovnsb_db,
136+
ovn_filter,
137+
show_flows,
138+
cookie_flag,
139+
heat_map,
140+
):
80141
"""
81142
Print the logical structure of the flows.
82143
@@ -88,6 +149,11 @@ def logic(opts, show_flows, cookie_flag, heat_map):
88149
Optionally, the cookie can also be considered to be part of the logical
89150
flow.
90151
"""
152+
if ovn_detrace_flag:
153+
opts["ovn_detrace_flag"] = True
154+
if opts.get("ovn_detrace_flag"):
155+
cookie_flag = True
156+
91157
processor = LogicFlowProcessor(opts, factory, cookie_flag)
92158
processor.process()
93159
processor.print(show_flows, heat_map)
@@ -159,3 +225,58 @@ def html(opts):
159225
processor = HTMLProcessor(opts, factory)
160226
processor.process()
161227
print(processor.html())
228+
229+
230+
@openflow.command()
231+
@click.option(
232+
"-d",
233+
"--ovn-detrace",
234+
"ovn_detrace_flag",
235+
is_flag=True,
236+
show_default=True,
237+
help="Use ovn-detrace to extract cookie information",
238+
)
239+
@click.option(
240+
"--ovn-detrace-path",
241+
default="/usr/bin",
242+
type=click.Path(),
243+
help="Use an alternative path to where ovn_detrace.py is located. "
244+
"Instead of using this option you can just set PYTHONPATH accordingly",
245+
show_default=True,
246+
callback=ovn_detrace_callback,
247+
)
248+
@click.option(
249+
"--ovnnb-db",
250+
default=os.getenv("OVN_NB_DB") or "unix:/var/run/ovn/ovnnb_db.sock",
251+
help="Specify the OVN NB database string (implies -d). "
252+
"If the OVN_NB_DB environment variable is set, it's used as default. "
253+
"Otherwise, the default is unix:/var/run/ovn/ovnnb_db.sock",
254+
callback=ovn_detrace_callback,
255+
)
256+
@click.option(
257+
"--ovnsb-db",
258+
default=os.getenv("OVN_SB_DB") or "unix:/var/run/ovn/ovnsb_db.sock",
259+
help="Specify the OVN NB database string (implies -d). "
260+
"If the OVN_NB_DB environment variable is set, it's used as default. "
261+
"Otherwise, the default is unix:/var/run/ovn/ovnnb_db.sock",
262+
callback=ovn_detrace_callback,
263+
)
264+
@click.option(
265+
"-o",
266+
"--ovn-filter",
267+
help="Specify a filter to be run on ovn-detrace information (implied -d). "
268+
"Format: python regular expression "
269+
"(see https://docs.python.org/3/library/re.html)",
270+
callback=ovn_detrace_callback,
271+
)
272+
@click.pass_obj
273+
def cookie(
274+
opts, ovn_detrace_flag, ovn_detrace_path, ovnnb_db, ovnsb_db, ovn_filter
275+
):
276+
"""Print the flow tables sorted by cookie"""
277+
if ovn_detrace_flag:
278+
opts["ovn_detrace_flag"] = True
279+
280+
processor = CookieProcessor(opts, factory)
281+
processor.process()
282+
processor.print()

0 commit comments

Comments
 (0)