cleanup appendix
This commit is contained in:
parent
27d4d449aa
commit
60a4d08514
2 changed files with 106 additions and 372 deletions
BIN
doc/Thesis.pdf
BIN
doc/Thesis.pdf
Binary file not shown.
478
doc/appendix.tex
478
doc/appendix.tex
|
@ -1052,6 +1052,112 @@ for P4/NetFPGA:
|
|||
ERROR: failed to convert 42540766411362381960998550477184434179 of type <type 'long'> to an integer
|
||||
nico@nsg-System:~/master-thesis/netpfga/minip4/sw/CLI$
|
||||
\end{verbatim}
|
||||
A P4/BMV2 compiler error:
|
||||
\begin{verbatim}
|
||||
Warning: you requested the nanomsg event logger, but bmv2 was compiled without -DBMELOG, and the event logger cannot be activated
|
||||
Calling target program-options parser
|
||||
[14:01:44.334] [bmv2] [D] [thread 23356] Set default default entry for table 'MyIngress.icmp6': MyIngress.controller_debug_table_id - 2,
|
||||
[14:01:44.341] [bmv2] [D] [thread 23356] Set default default entry for table 'MyIngress.nat64': MyIngress.controller_debug_table_id - 1,
|
||||
[14:01:44.344] [bmv2] [D] [thread 23356] Set default default entry for table 'tbl_act': act -
|
||||
[14:01:44.345] [bmv2] [D] [thread 23356] Set default default entry for table 'tbl_act_0': act_0 -
|
||||
[14:01:44.345] [bmv2] [D] [thread 23356] Set default default entry for table 'tbl_nat64_icmp6_generic': MyIngress.nat64_icmp6_generic -
|
||||
[14:01:44.345] [bmv2] [D] [thread 23356] Set default default entry for table 'tbl_act_1': act_1 -
|
||||
[14:01:44.345] [bmv2] [D] [thread 23356] Set default default entry for table 'tbl_act_2': act_2 -
|
||||
[14:01:44.345] [bmv2] [D] [thread 23356] Set default default entry for table 'MyIngress.v4_networks': MyIngress.controller_debug_table_id - 5,
|
||||
[14:01:44.345] [bmv2] [D] [thread 23356] Set default default entry for table 'MyIngress.v6_networks': MyIngress.controller_debug_table_id - 3,
|
||||
[14:01:44.346] [bmv2] [D] [thread 23356] Set default default entry for table 'tbl_act_3': act_3 -
|
||||
Invalid entry type 'expression' in field list
|
||||
bad json:
|
||||
{
|
||||
"type" : "expression",
|
||||
"value" : {
|
||||
"type" : "expression",
|
||||
"value" : {
|
||||
"left" : null,
|
||||
"op" : "d2b",
|
||||
"right" : {
|
||||
"type" : "field",
|
||||
"value" : [ "scalars", "metadata.chk_icmp6_na_ns" ]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
\end{verbatim}
|
||||
|
||||
Inability of P4/BMV2 to have multiple LPM keys in a table:
|
||||
\begin{verbatim}
|
||||
../p4src/static-mapping.p4(121): error: MyIngress.nat64, Multiple LPM keys in table
|
||||
table nat64 {
|
||||
^^^^^
|
||||
Compilation Error
|
||||
|
||||
table nat64 {
|
||||
key = {
|
||||
hdr.ipv6.src_addr: lpm;
|
||||
hdr.ipv6.dst_addr: lpm;
|
||||
}
|
||||
actions = {
|
||||
controller_debug;
|
||||
nat64_static;
|
||||
NoAction;
|
||||
}
|
||||
size = NAT64_TABLE_SIZE;
|
||||
default_action = controller_debug;
|
||||
}
|
||||
\end{verbatim}
|
||||
Switch statements are not allowed in P4/BMV:
|
||||
\begin{verbatim}
|
||||
../p4src/static-mapping.p4(60): error: SwitchStatement: switch statements not allowed in actions
|
||||
switch(hdr.icmp6.type) {
|
||||
^^^^^^
|
||||
\end{verbatim}
|
||||
And also no ifs in actions:
|
||||
\begin{verbatim}
|
||||
../p4src/static-mapping.p4(57): error: MethodCallStatement: Conditional execution in actions is not supported on this target
|
||||
hdr.icmp.setValid();
|
||||
^^^^^^^^^^^^^^^^^^^
|
||||
../p4src/static-mapping.p4(70): error: MethodCallStatement: Conditional execution in actions is not supported on this target
|
||||
hdr.icmp6.setInvalid();
|
||||
^^^^^^^^^^^^^^^^^^^^^^
|
||||
../p4src/static-mapping.p4(73): error: MethodCallStatement: Conditional execution in actions is not supported on this target
|
||||
hdr.icmp6_na_ns.setInvalid();
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
../p4src/static-mapping.p4(74): error: MethodCallStatement: Conditional execution in actions is not supported on this target
|
||||
hdr.icmp6_option_link_layer_addr.setInvalid();
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
Compilation Error
|
||||
p4@ubuntu:~/master-thesis/p4app$
|
||||
|
||||
if(hdr.ipv6.next_header == PROTO_ICMP6) {
|
||||
nat64_icmp6();
|
||||
}
|
||||
\end{verbatim}
|
||||
Compiler bug in P4/BMV2:
|
||||
\begin{verbatim}
|
||||
p4c --target bmv2 --arch v1model --std p4-16 "../p4src/checksum_diff.p4" -o "/home/p4/master-thesis/p4src"
|
||||
In file: /home/p4/p4-tools/p4c/backends/bmv2/common/expression.cpp:168
|
||||
Compiler Bug: ../p4src/actions_delta_checksum.p4(60): ones_complement_sum(hdr.udp.checksum, tmp);: unhandled case
|
||||
tmp = ones_complement_sum(hdr.udp.checksum, meta.v6sum);
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Compilation Error```
|
||||
Using the following code:
|
||||
```/* copied from
|
||||
https://p4.org/p4-spec/docs/PSA-v1.1.0.html#appendix-internetchecksum-implementation
|
||||
*/
|
||||
|
||||
bit<16> ones_complement_sum(in bit<16> x, in bit<16> y) {
|
||||
bit<17> ret = (bit<17>) x + (bit<17>) y;
|
||||
if (ret[16:16] == 1) {
|
||||
ret = ret + 1;
|
||||
}
|
||||
return ret[15:0];
|
||||
}```
|
||||
And p4c version:
|
||||
```p4@ubuntu:~/master-thesis/p4app$ p4c --version
|
||||
p4c 0.5 (SHA: 5ae30ee)```
|
||||
\end{verbatim}
|
||||
|
||||
%----------------------------------------------------------------------
|
||||
\chapter{\label{benchmark}Benchmark Logs}
|
||||
% ----------------------------------------------------------------------
|
||||
|
@ -1287,378 +1393,6 @@ PING 10.0.1.66 (10.0.1.66) 56(84) bytes of data.
|
|||
rtt min/avg/max/mdev = 0.218/0.259/0.281/0.034 ms
|
||||
nico@ESPRIMO-P956:~/master-thesis/iperf$
|
||||
\end{verbatim}
|
||||
|
||||
|
||||
|
||||
% ----------------------------------------------------------------------
|
||||
\section{P4 error messages}
|
||||
|
||||
\begin{verbatim}
|
||||
Warning: you requested the nanomsg event logger, but bmv2 was compiled without -DBMELOG, and the event logger cannot be activated
|
||||
Calling target program-options parser
|
||||
[14:01:44.334] [bmv2] [D] [thread 23356] Set default default entry for table 'MyIngress.icmp6': MyIngress.controller_debug_table_id - 2,
|
||||
[14:01:44.341] [bmv2] [D] [thread 23356] Set default default entry for table 'MyIngress.nat64': MyIngress.controller_debug_table_id - 1,
|
||||
[14:01:44.344] [bmv2] [D] [thread 23356] Set default default entry for table 'tbl_act': act -
|
||||
[14:01:44.345] [bmv2] [D] [thread 23356] Set default default entry for table 'tbl_act_0': act_0 -
|
||||
[14:01:44.345] [bmv2] [D] [thread 23356] Set default default entry for table 'tbl_nat64_icmp6_generic': MyIngress.nat64_icmp6_generic -
|
||||
[14:01:44.345] [bmv2] [D] [thread 23356] Set default default entry for table 'tbl_act_1': act_1 -
|
||||
[14:01:44.345] [bmv2] [D] [thread 23356] Set default default entry for table 'tbl_act_2': act_2 -
|
||||
[14:01:44.345] [bmv2] [D] [thread 23356] Set default default entry for table 'MyIngress.v4_networks': MyIngress.controller_debug_table_id - 5,
|
||||
[14:01:44.345] [bmv2] [D] [thread 23356] Set default default entry for table 'MyIngress.v6_networks': MyIngress.controller_debug_table_id - 3,
|
||||
[14:01:44.346] [bmv2] [D] [thread 23356] Set default default entry for table 'tbl_act_3': act_3 -
|
||||
Invalid entry type 'expression' in field list
|
||||
bad json:
|
||||
{
|
||||
"type" : "expression",
|
||||
"value" : {
|
||||
"type" : "expression",
|
||||
"value" : {
|
||||
"left" : null,
|
||||
"op" : "d2b",
|
||||
"right" : {
|
||||
"type" : "field",
|
||||
"value" : [ "scalars", "metadata.chk_icmp6_na_ns" ]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
\end{verbatim}
|
||||
|
||||
\begin{verbatim}
|
||||
../p4src/static-mapping.p4(121): error: MyIngress.nat64, Multiple LPM keys in table
|
||||
table nat64 {
|
||||
^^^^^
|
||||
Compilation Error
|
||||
|
||||
table nat64 {
|
||||
key = {
|
||||
hdr.ipv6.src_addr: lpm;
|
||||
hdr.ipv6.dst_addr: lpm;
|
||||
}
|
||||
actions = {
|
||||
controller_debug;
|
||||
nat64_static;
|
||||
NoAction;
|
||||
}
|
||||
size = NAT64_TABLE_SIZE;
|
||||
default_action = controller_debug;
|
||||
}
|
||||
|
||||
\end{verbatim}
|
||||
|
||||
\begin{verbatim}
|
||||
../p4src/static-mapping.p4(60): error: SwitchStatement: switch statements not allowed in actions
|
||||
switch(hdr.icmp6.type) {
|
||||
^^^^^^
|
||||
\end{verbatim}
|
||||
|
||||
No if in actions:
|
||||
|
||||
\begin{verbatim}
|
||||
../p4src/static-mapping.p4(57): error: MethodCallStatement: Conditional execution in actions is not supported on this target
|
||||
hdr.icmp.setValid();
|
||||
^^^^^^^^^^^^^^^^^^^
|
||||
../p4src/static-mapping.p4(70): error: MethodCallStatement: Conditional execution in actions is not supported on this target
|
||||
hdr.icmp6.setInvalid();
|
||||
^^^^^^^^^^^^^^^^^^^^^^
|
||||
../p4src/static-mapping.p4(73): error: MethodCallStatement: Conditional execution in actions is not supported on this target
|
||||
hdr.icmp6_na_ns.setInvalid();
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
../p4src/static-mapping.p4(74): error: MethodCallStatement: Conditional execution in actions is not supported on this target
|
||||
hdr.icmp6_option_link_layer_addr.setInvalid();
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
Compilation Error
|
||||
p4@ubuntu:~/master-thesis/p4app$
|
||||
|
||||
if(hdr.ipv6.next_header == PROTO_ICMP6) {
|
||||
nat64_icmp6();
|
||||
}
|
||||
\end{verbatim}
|
||||
|
||||
\begin{verbatim}
|
||||
p4c --target bmv2 --arch v1model --std p4-16 "../p4src/checksum_diff.p4" -o "/home/p4/master-thesis/p4src"
|
||||
In file: /home/p4/p4-tools/p4c/backends/bmv2/common/expression.cpp:168
|
||||
Compiler Bug: ../p4src/actions_delta_checksum.p4(60): ones_complement_sum(hdr.udp.checksum, tmp);: unhandled case
|
||||
tmp = ones_complement_sum(hdr.udp.checksum, meta.v6sum);
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Compilation Error```
|
||||
Using the following code:
|
||||
```/* copied from
|
||||
https://p4.org/p4-spec/docs/PSA-v1.1.0.html#appendix-internetchecksum-implementation
|
||||
*/
|
||||
|
||||
bit<16> ones_complement_sum(in bit<16> x, in bit<16> y) {
|
||||
bit<17> ret = (bit<17>) x + (bit<17>) y;
|
||||
if (ret[16:16] == 1) {
|
||||
ret = ret + 1;
|
||||
}
|
||||
return ret[15:0];
|
||||
}```
|
||||
And p4c version:
|
||||
```p4@ubuntu:~/master-thesis/p4app$ p4c --version
|
||||
p4c 0.5 (SHA: 5ae30ee)```
|
||||
\end{verbatim}
|
||||
|
||||
% ----------------------------------------------------------------------
|
||||
\section{Traces}
|
||||
|
||||
Proof of stuff working, reference for each stage / feature
|
||||
|
||||
Stuff that needs to be cleaned up
|
||||
|
||||
|
||||
% ----------------------------------------------------------------------
|
||||
\subsection{P4/BMV NAT64 Delta based traces}
|
||||
\begin{verbatim}
|
||||
*** DONE 2019-07-21: Proof of v6->v4 working delta based
|
||||
CLOSED: [2019-07-21 Sun 12:30]
|
||||
#+BEGIN_CENTER
|
||||
pcap/tcp-udp-delta-from-v6-2019-07-21-0853-h1.pcap | Bin 0 -> 4252 bytes
|
||||
pcap/tcp-udp-delta-from-v6-2019-07-21-0853-h3.pcap | Bin 0 -> 2544 bytes
|
||||
#+END_CENTER
|
||||
|
||||
\end{verbatim}
|
||||
|
||||
|
||||
\begin{verbatim}
|
||||
create mode 100644 pcap/tcp-udp-delta-2019-07-17-1555-h1.pcap
|
||||
create mode 100644 pcap/tcp-udp-delta-2019-07-17-1555-h3.pcap
|
||||
create mode 100644 pcap/tcp-udp-delta-2019-07-17-1557-h1.pcap
|
||||
create mode 100644 pcap/tcp-udp-delta-2019-07-17-1558-h3.pcap
|
||||
\end{verbatim}
|
||||
|
||||
|
||||
% ----------------------------------------------------------------------
|
||||
\subsection{P4/NetFPGA NAT64 Delta based traces}
|
||||
\begin{verbatim}
|
||||
**** DONE Testing v4->v6 tcp: ok (version 10.0)
|
||||
CLOSED: [2019-08-04 Sun 09:15]
|
||||
#+BEGIN_CENTER
|
||||
nico@ESPRIMO-P956:~/master-thesis/bin$ ./socat-connect-tcp-v4
|
||||
+ echo from-v4-ok
|
||||
+ socat - TCP:10.0.0.66:2345
|
||||
TCPv6-ok
|
||||
nico@ESPRIMO-P956:~/master-thesis/bin$ ./socat-listen-tcp-v6
|
||||
from-v4-ok
|
||||
|
||||
#+END_CENTER
|
||||
|
||||
trace:
|
||||
netfpga-nat64-2019-08-04-0907-enp2s0f0.pcap
|
||||
netfpga-nat64-2019-08-04-0907-enp2s0f1.pcap
|
||||
|
||||
**** DONE Testing v4->v6 udp: ok (version 10.1)
|
||||
trace:
|
||||
create mode 100644 pcap/netfpga-nat64-udp-2019-08-04-0913-enp2s0f0.pcap
|
||||
create mode 100644 pcap/netfpga-nat64-udp-2019-08-04-0913-enp2s0f1.pcap
|
||||
|
||||
\end{verbatim}
|
||||
|
||||
Bigger packets
|
||||
\begin{verbatim}
|
||||
*** DONE 2019-08-04: version 10.1/10.2: new maxpacketregion: v4->v6 works
|
||||
CLOSED: [2019-08-04 Sun 19:42]
|
||||
#+BEGIN_CENTER
|
||||
nico@ESPRIMO-P956:~/master-thesis/bin$ ./init_ipv4_esprimo.sh
|
||||
nico@ESPRIMO-P956:~/master-thesis/bin$ ./set_ipv4_neighbor.sh
|
||||
|
||||
#+END_CENTER
|
||||
|
||||
Test 20 first:
|
||||
|
||||
- Does't work -> missed to add table entries
|
||||
- Does work after setting table entries
|
||||
- 300 works
|
||||
- 1450 works
|
||||
- 1500 does not work
|
||||
|
||||
Proof:
|
||||
|
||||
create mode 100644 pcap/netfpga-10.2-maxpacket-2019-08-04-1931-enp2s0f0.pcap
|
||||
create mode 100644 pcap/netfpga-10.2-maxpacket-2019-08-04-1931-enp2s0f1.pcap
|
||||
|
||||
\end{verbatim}
|
||||
\begin{verbatim}
|
||||
*** DONE 2019-08-04: test v6 -> v4: works for 1420
|
||||
CLOSED: [2019-08-04 Sun 20:30]
|
||||
|
||||
Proof:
|
||||
#+BEGIN_CENTER
|
||||
create mode 100644 pcap/netfpga-10.2-fromv6tov4-2019-08-04-1943-enp2s0f0.pcap
|
||||
create mode 100644 pcap/netfpga-10.2-fromv6tov4-2019-08-04-1943-enp2s0f1.pcap
|
||||
|
||||
|
||||
\end{verbatim}
|
||||
|
||||
% ----------------------------------------------------------------------
|
||||
|
||||
\section{Introduction}
|
||||
|
||||
\subsection{\label{introduction:taskdescription}The Task}
|
||||
- Milestone 1: Stateless NAT64/NAT46 translations in P4
|
||||
- Milestone 2: Stateful (dynamic) NAT64/NAT46 translations
|
||||
- Milestone 3: Hardware adaption
|
||||
|
||||
This thesis is
|
||||
into 3 milestone
|
||||
P4 environment
|
||||
a lot of potential
|
||||
Programming language in the network
|
||||
Not only faster, but also more convienient.
|
||||
|
||||
**** High speed NAT64 with P4
|
||||
Currently there are two main open source NAT64 solution available:
|
||||
tayga and jool. The former is a single threaded, cpu bound user
|
||||
space solution, the latter a custom Linux kernel module.
|
||||
|
||||
This thesis challenges this status quo by developing a P4 based
|
||||
solution supporting all features of jool/tayga and comparing the
|
||||
performance, security and adaptivity of the solutions.
|
||||
|
||||
|
||||
Describe your task.
|
||||
|
||||
|
||||
\begin{verbatim}
|
||||
|
||||
***** Motivation zeigen
|
||||
***** IPv6, NetPFGA mehr Möglichketien
|
||||
***** P4 erwähnen
|
||||
***** Task gut zu zeigen, alles erreicht
|
||||
use cases / sample applications
|
||||
|
||||
|
||||
\end{verbatim}
|
||||
|
||||
% ----------------------------------------------------------------------
|
||||
\section{\label{appendix:p4}P4 notes}
|
||||
% ----------------------------------------------------------------------
|
||||
\subsection{\label{appendix:p4:keyretrieval}Key retrieval chat log}
|
||||
\begin{verbatim}
|
||||
Key and mask for matching destination is in table. We need this
|
||||
information in the action. However this information is not exposed, so
|
||||
we need to specify another parameter with the same information as in
|
||||
the key(s).
|
||||
|
||||
Log from slack: (2019-03-14)
|
||||
|
||||
nico [1:55 PM]
|
||||
If I use LPM for matching, can I easily get the network address from P4 or do I have to use a bitmask myself? In the latter case it is not exactly clear how to get the mask from the table
|
||||
|
||||
Nate Foster [1:58 PM]
|
||||
You want to retrieve the address in the packet? In a table?
|
||||
And do you want to do the retrieving from the data plane or the control plane? (edited)
|
||||
|
||||
nico [2:00 PM]
|
||||
If I have a match in a table that matches on LPM, it can be any IP address in a network
|
||||
For calculating the NAT64/NAT46 translation, I will need the base address, i.e. network address to do subtractions/additions
|
||||
So it is fully data plane, what I would like to do
|
||||
I'll commit sample code to show the use case more clearly
|
||||
https://gitlab.ethz.ch/nicosc/master-thesis/blob/master/p4src/static-mapping.p4#L73
|
||||
GitLab
|
||||
p4src/static-mapping.p4 · master · nicosc / master-thesis
|
||||
gitlab.ethz.ch
|
||||
So the action nat64_static() is used in the table v6_networks.
|
||||
In v6_networks I use a match on `hdr.ipv6.dst_addr: lpm;`
|
||||
What I would like to be able is to get the network address ; I can do that manually, if I have the mask
|
||||
I can also re-inject this parameter by another action argument, but I'd assume that I can somewhere read this out from the table / match
|
||||
|
||||
Nate Foster [2:15 PM]
|
||||
To make sure I understand, in the data plane, you want to retrieve the address in the lpm pattern? (edited)
|
||||
|
||||
nico [2:16 PM]
|
||||
I want to retrieve the key
|
||||
|
||||
Nate Foster [2:16 PM]
|
||||
Wait. The value `hdr.ipv6.dst_addr` is the thing used in the match.
|
||||
So you have that.
|
||||
What you don’t have is the IPv6 address and mask put into the table by the control plane.
|
||||
I assume you want the latter, right?
|
||||
|
||||
nico [2:17 PM]
|
||||
For example, if my matching key is 2001:db8::/32 and the real address is 2001:db8::f00, then I would like to retrieve 2001:db8:: and 32 from the table
|
||||
exactly :slightly_smiling_face:
|
||||
I can "fix" this by adding another argument, but it feels somewhat wrong to do that
|
||||
Because the table already knows this information
|
||||
|
||||
Nate Foster [2:26 PM]
|
||||
I can’t think of a way other than the action parameter hack.
|
||||
|
||||
nico [2:26 PM]
|
||||
Oh, ok
|
||||
Is it because the information is "lost in hardware"?
|
||||
|
||||
Nate Foster [2:31 PM]
|
||||
No you’re right that most implementations have the value in memory. And one can imagine a different table API that allowed one to retrieve it in the data plane.
|
||||
But unless I am missing something obvious, P4 hides it…
|
||||
|
||||
\end{verbatim}
|
||||
|
||||
% ----------------------------------------------------------------------
|
||||
\subsection{\label{appendix:p4:tableretrieval}Table retrieval problem}
|
||||
\begin{verbatim}
|
||||
Is there any meta information for "from which table was the action
|
||||
called" available? My use case is having a debug action that sends
|
||||
packets to the controller and I use it as a default_action in various
|
||||
tables; however know I don't know anymore from which table the action
|
||||
was called. Is there any kind of meta information which table called
|
||||
me available?
|
||||
|
||||
I could work around this by using if(! .. .hit) { my_action(table_id)
|
||||
}, but it would not work with using default_action = ...
|
||||
|
||||
\end{verbatim}
|
||||
|
||||
\begin{verbatim}
|
||||
Is there any meta information for "from which table was the action
|
||||
called" available? My use case is having a debug action that sends
|
||||
packets to the controller and I use it as a default_action in various
|
||||
tables; however know I don't know anymore from which table the action
|
||||
was called. Is there any kind of meta information which table called
|
||||
me available?
|
||||
|
||||
I could work around this by using if(! .. .hit) { my_action(table_id)
|
||||
}, but it would not work with using default_action = ...
|
||||
|
||||
\end{verbatim}
|
||||
% ----------------------------------------------------------------------
|
||||
\subsection{\label{appendix:p4:datadefinition}Data definition
|
||||
redundancy}
|
||||
\begin{verbatim}
|
||||
*** DONE Synchronisation with the controller
|
||||
- Double data type definition -> might differ
|
||||
- TYPE_CPU for ethernet
|
||||
- Port ingress offset (9 vs. 16 bit)
|
||||
|
||||
\end{verbatim}
|
||||
|
||||
% ----------------------------------------------------------------------
|
||||
\subsection{\label{appendix:p4:python2unicode}Python2 unicode issue}
|
||||
|
||||
\begin{verbatim}
|
||||
ipaddress.ip_network("2001:db8:61::/64")
|
||||
IPv6Network(u'3230:3031:3a64:6238:3a36:313a:3a2f:3634/128')
|
||||
|
||||
Fix:
|
||||
from __future__ import unicode_literals
|
||||
|
||||
\end{verbatim}
|
||||
% ----------------------------------------------------------------------
|
||||
\subsection{\label{appendix:p4:p4os}P4 OS}
|
||||
|
||||
\begin{verbatim}
|
||||
Not addressed so far: how to create re-usable code fragments that can
|
||||
be plugged in easily. There could be a hypothetical "P4OS" that
|
||||
manages code fragments. This might include, but not limited to
|
||||
downloading (signed?) source code, managing dependencies similar to
|
||||
Linux package management, handling updates, etc.
|
||||
|
||||
\end{verbatim}
|
||||
|
||||
|
||||
|
||||
%---------------------------------------------------------------------------------------------------------
|
||||
\printnomenclature
|
||||
\abbrev{ARP}{Address resolution protocol}
|
||||
|
|
Loading…
Reference in a new issue