📜 ⬆️ ⬇️

About configuring Open vSwitch a difficult language

From translator
SDN — software defined networks — have become firmly established in our lives, but there is not a lot of materials about their low-level work in Russian. I bring to your attention a translation of the tutorial article , which shows an example of creating an autonomous virtual switch with VLAN support. Such a switch in its basic functionality can work without a network controller. It is assumed. that the reader is familiar with the basics and terminology of building networks in general, and also has a general understanding of software-defined networks.

Terms used:

OpenFlow is a protocol for controlling data transfer over a network. It describes the process of interaction between the controller and the switch, as well as the format of the rules loaded into the switch.
Open vSwitch is a software implementation of the switch compatible with the OpenFlow protocol. It is used to manage traffic in virtualization systems, for example, OpenStack and oVirt (experimentally).
802.1Q (VLAN) is a mechanism for delimiting traffic both within a single switch and in a local network. Based on embedding VLAN tag (number) in data packet
802.1p (QoS) is a traffic prioritization control mechanism. Part of the 802.1Q standard
A port of aggregation (trunk port) is a switch port connected to an upstream switch. The aggregation port allows sending packets with any VLAN number
Access port (access port) - the switch port, allowing work with packets only certain VLAN.

Introduction


There are many openflow tutorials on the web, but this article is about something else. However, for understanding this article, basic knowledge about OpenFlow is required. If you do not fully understand how OpenFlow rules work, please learn the basics , and then return to this article.
Also, you will need knowledge of the basics of Open vSwitch. If you have never used the ovs-vsctl or ovs-ofctl management utilities , you should read a little about them before we proceed.
')
Most of the features described in this guide relate to the enhanced version of the OpenFlow protocol implemented in the Open vSwitch. If you use a hardware implementation as a switch based on an ASIC chip, this guide is unlikely to help you.

We will not consider in detail all the ins and outs of the technologies that will be discussed. For details, you can refer to the Open vSwitch documentation, in particular, to the ovs-vsctl help files, as well as the comments in the include / openflow / nicira-ext.h and include / openvswitch / meta-flow.h files .

Getting started


We assume that the Open vSwitch executable files are already installed on your system. Any specialized hardware other than the computer itself is not required. Instead, we will use the ovs-sandbox script, which can be found here . This script is needed to create a software-defined network environment based on Open vSwitch.

You can use the ovs-sandbox in three ways:


The script does the following:

  1. ATTENTION: deletes all subdirectories from the subdirectory named sandbox of the current directory and all files in this subdirectory
  2. Creates a new “sandbox” directory in the current directory.
  3. Sets the environment variables so that the Open vSwitch utilities use the “sandbox” as the current directory, rather than the Open vSwitch installation directory
  4. If you compiled Open vSwitch, but did not install it, copies the help files to the “sandbox” subdirectory and writes the name of this subdirectory to the MANPATH environment variable. This means that when you use, for example, the man ovs-vsctl command, you will see the help for the version of Open vSwitch that you compiled.
  5. Creates an empty Open vSwitch configuration database in the “sandbox” directory
  6. Runs the ovsdb-server in the “sandbox” directory
  7. It launches ovs-vswitchd in the “sandbox” directory and sends it parameters for a special test mode.
  8. Starts an interactive shell session from the sandbox directory.

From this point on, you can run all the familiar Open vSwitch commands from a shell session. For example, you can run ovs-vsctl and create a virtual switch:

 $ ovs-vsctl add-br br0 

From the point of view of Open vSwitch, the switch you created is just as real as any other. For example, you can connect it to an OpenFlow controller or use ovs-ofctl to check and modify traffic control rules. On the other hand, the switch does not appear in the network configuration of the host, so ifconfig and ip utilities cannot work with it. In addition, the ping and tcpdump utilities will not work either. But this has a good side - you can’t knock down the host’s network settings by changing the switch settings in the sandbox.

When you need to finish working with Open vSwitch, just type in the shell “exit” command or press Ctrl + D. This will complete the processes started by the ovs-sandbox script, but leave in place the sandbox directory itself with all its contents.

The “sandbox” directory contains log files for all Open vSwitch services, so that you can review them after you have finished working with Open vSwitch.

Using the GDB Debugger


This training material does not require the use of the GDB debugger without fail, however you can use GDB to figure out the internal structure of the Open vSwitch utilities.

GDB can be used to debug any process that is already running using the gdb <process-id> command.

The ovs-sandbox script has the -g option to run ovs-vswitchd under GDB. The parameter can be used if you need to set breakpoints before executing ovs-vswitchd or to debug a crash early in the service startup. In addition, there is the -d parameter, which runs the ovsdb-server service under GDB. Both parameters can be used simultaneously.

There is also the -e option, which also runs the ovs-vswitchd service under GDB, but does not display the gdb> prompt and does not wait for commands to be entered, but immediately starts the execution of the service. The -r option causes the ovsdb-server service to start under GDB right away, like ovs-vswitchd.

To avoid incorrect terminal behavior when starting GDB, the ovs-sandbox script opens a new xterm session for each GDB session. For systems without a graphical X Windows server, GDB support is disabled.

When you run the test environment from the makefile, you can pass the -g parameter to the script via the SANDBOXFLAGS environment variable. Thus, the make sandbox command SANDBOXFLAGS = -g runs the test environment with the ovs-vswitchd service under the GDB debugger in a separate X-terminal.

Formulation of the problem


The main goal of this tutorial is to demonstrate the extensive capabilities of Open vSwitch in traffic management. In the course of work, we will build a switch capable of storing MAC addresses and having access and aggregation ports separated by VLANs. If you do not consider the functions of Open vSwitch, which we will talk about below, OpenFlow offers at least two ways to implement such a switch.


Unfortunately, both approaches are not without flaws. In the first case, the use of the controller leads to a significant reduction in bandwidth and increased delays. In addition, the controller does not scale well to service a large number of switches, which is especially important in an environment with thousands of hypervisors, each of which has its own OpenFlow switch. Naturally, memorizing MAC addresses using a controller will not work if the controller is out of order, slowly processes requests, or is unavailable due to network problems.

In the second case (NORMAL) we deal with problems of a different kind. Firstly, only a small part of the “normal” behavior is standardized and works differently on the equipment of different manufacturers. The available functions and methods for configuring them (as a rule, not through OpenFlow) differ from different manufacturers. Secondly, the NORMAL mode does not work well with other OpenFlow rules. NORMAL implements the concept of “all or nothing” and has a very narrow potential for customizing its behavior or interaction with other functions.

Test script


We will build an OpenFlow switch and configure its tables for storing MAC addresses and working with VLANs. The switch will have 4 ports:


The names of the ports do not matter, you can call them eth1-eth4 or some other way you wish.
The OpenFlow switch also has one port, visible on the host as a local interface. Our script does not provide for its use.

Our switch will include 5 tables with rules, each of which implements its part of the traffic processing pipeline.


Below you will see how to create such a switch table by table.

You can copy the ovs-vsctl and ovs-ofctl commands with the parameters from the examples below and paste them into the command shell created by ovs-sandbox. The ovs-appctl command with parameters is intended for tests and should not be used separately from other examples.

Installation


Run the ovs-sandbox and in the opened interactive shell enter the following command:

 $ ovs-vsctl add-br br0 -- set Bridge br0 fail-mode=secure 

This command creates a new virtual switch br0 and puts it into the so-called fail-secure mode. For us, for the time being, it will only mean that the switch will start with empty tables.

If we do not do this, the switch will start with the only rule that works out the NORMAL behavior. We can use this feature to build the same switch as ours, but with the limitations described above in the “Problem Definition” section.

The new switch has only one port so far - the local br0. We need to add ports p1, p2, p3 and p4. The for shell command is one way to do this:

 $ for i in 1 2 3 4; do ovs-vsctl add-port br0 p$i -- set Interface p$i ofport_request=$i ovs-ofctl mod-port br0 p$i up done 

The commands not only add ports, but also set the ofport_request attribute so that port p1 corresponds to port 1 OpenFlow, port 2 to port 2 OpenFlow, and so on.

We can skip the setting of the attribute ofport_request and let OpenFlow choose ports itself, but for learning purposes we will assign port numbers ourselves to talk, for example, about port 1 of OpenFlow and to know that it refers to port p1.

The ovs-ofctl command, using the OpenFlow request, runs the interfaces that are disabled during creation. The same effect is caused by running the ifconfig up command, but the test environment interfaces are not displayed in the host OS and ifconfig cannot manage them.

We have not yet configured the VLANs and MAC address memorization, as we plan to do this below using the traffic management tables.

To see the result of our work, you can use the commands ovs-vsctl show or ovs-ofctl show br0.

Create table 0: Input control


Table 0 includes packets that have just arrived at the switch. We will use it to reject packets for one reason or another. For example, the packet with the sender's broadcast address is incorrect, so we can drop it at the entrance to the switch.

 $ ovs-ofctl add-flow br0 "table=0, dl_src=01:00:00:00:00:00/01:00:00:00:00:00, actions=drop" 

The switch also does not have to forward any further IEEE 802.1D Spanning Tree Protocol (STP) packets, so we add a rule to discard such packets and packets of other reserved multicast protocols:

 $ ovs-ofctl add-flow br0 "table=0, dl_dst=01:80:c2:00:00:00/ff:ff:ff:ff:ff:f0, actions=drop" 

We can add rules for rejecting packets of other protocols according to the principle shown above.

We need another rule with priority below the default priority, so that packets that are not rejected by the higher rules go to the next stage — in Table 1 of OpenFlow.

 $ ovs-ofctl add-flow br0 "table=0, priority=0, actions=resubmit(,1)" 

The resubmit action is part of the Open vSwitch extension for OpenFlow.

Check table 0


If we use Open vSwitch to configure a physical or virtual switch, we need to test it by sending packets in different ways, for example, using the well-known ping and tcpdump utilities or more specialized tools like Scapy. This is difficult for our virtual switch because it is invisible to the operating system.

However, the virtual switch has several special tools for testing. The widest functionality offers ofproto / trace. Taking the switch name and traffic description as input, ofproto / trace demonstrates step by step which rules will be affected by it.

Example 1


Try the command:

 $ ovs-appctl ofproto/trace br0 in_port=1,dl_dst=01:80:c2:00:00:05 

The output will be something like this:

 Bridge: br0 Flow: in_port=1,vlan_tci=0x0000,dl_src=00:00:00:00:00:00,dl_dst=01:80:c2:00:00:05,dl_type=0x0000 Rule: table=0 cookie=0 dl_dst=01:80:c2:00:00:00/ff:ff:ff:ff:ff:f0 OpenFlow actions=drop Final flow: unchanged Megaflow: recirc_id=0,in_port=1,dl_src=00:00:00:00:00:00/01:00:00:00:00:00,dl_dst=01:80:c2:00:00:00/ff:ff:ff:ff:ff:f0,dl_type=0x0000 Datapath actions: drop 

The first line shows the parameters of the package being processed in a more detailed form than we write on the command line.

The second few lines show the packet path inside the br0 switch. We see that in table 0 a corresponding rule was found with a certain priority and a given action. If a package falls under several rules, there will be several such lines.

The last group of lines displays the result. which we will not discuss in detail here.

Example 2


Let's try to execute the command

 $ ovs-appctl ofproto/trace br0 in_port=1,dl_dst=01:80:c2:00:00:10 

Its output will be as follows:

 Bridge: br0 Flow: in_port=1,vlan_tci=0x0000,dl_src=00:00:00:00:00:00,dl_dst=01:80:c2:00:00:10,dl_type=0x0000 Rule: table=0 cookie=0 priority=0 OpenFlow actions=resubmit(,1) Resubmitted flow: in_port=1,vlan_tci=0x0000,dl_src=00:00:00:00:00:00,dl_dst=01:80:c2:00:00:10,dl_type=0x0000 Resubmitted regs: reg0=0x0 reg1=0x0 reg2=0x0 reg3=0x0 reg4=0x0 reg5=0x0 reg6=0x0 reg7=0x0 reg8=0x0 reg9=0x0 reg10=0x0 reg11=0x0 reg12=0x0 reg13=0x0 reg14=0x0 reg15=0x0 Resubmitted odp: drop Resubmitted megaflow: recirc_id=0,in_port=1,dl_src=00:00:00:00:00:00/01:00:00:00:00:00,dl_dst=01:80:c2:00:00:10/ff:ff:ff:ff:ff:f0,dl_type=0x0000 Rule: table=254 cookie=0 priority=0,reg0=0x2 OpenFlow actions=drop Final flow: unchanged Megaflow: recirc_id=0,in_port=1,dl_src=00:00:00:00:00:00/01:00:00:00:00:00,dl_dst=01:80:c2:00:00:10/ff:ff:ff:ff:ff:f0,dl_type=0x0000 Datapath actions: drop 0x0 reg2 = 0x0 reg3 = 0x0 reg4 = 0x0 reg5 = 0x0 reg6 = 0x0 reg7 = 0x0 reg8 = 0x0 reg9 = 0x0 reg10 = 0x0 reg11 = 0x0 reg12 = 0x0 reg13 = 0x0 reg14 = 0x0 reg15 = Bridge: br0 Flow: in_port=1,vlan_tci=0x0000,dl_src=00:00:00:00:00:00,dl_dst=01:80:c2:00:00:10,dl_type=0x0000 Rule: table=0 cookie=0 priority=0 OpenFlow actions=resubmit(,1) Resubmitted flow: in_port=1,vlan_tci=0x0000,dl_src=00:00:00:00:00:00,dl_dst=01:80:c2:00:00:10,dl_type=0x0000 Resubmitted regs: reg0=0x0 reg1=0x0 reg2=0x0 reg3=0x0 reg4=0x0 reg5=0x0 reg6=0x0 reg7=0x0 reg8=0x0 reg9=0x0 reg10=0x0 reg11=0x0 reg12=0x0 reg13=0x0 reg14=0x0 reg15=0x0 Resubmitted odp: drop Resubmitted megaflow: recirc_id=0,in_port=1,dl_src=00:00:00:00:00:00/01:00:00:00:00:00,dl_dst=01:80:c2:00:00:10/ff:ff:ff:ff:ff:f0,dl_type=0x0000 Rule: table=254 cookie=0 priority=0,reg0=0x2 OpenFlow actions=drop Final flow: unchanged Megaflow: recirc_id=0,in_port=1,dl_src=00:00:00:00:00:00/01:00:00:00:00:00,dl_dst=01:80:c2:00:00:10/ff:ff:ff:ff:ff:f0,dl_type=0x0000 Datapath actions: drop 

In this case, the packet does not match any rule with the “drop” action in table 0, so that it falls under the rule with the resubmit action. The resubmit action redirects the packet to table 1, which is shown in row

 OpenFlow actions=resubmit(,1) 

We have not yet added any rules to OpenFlow Table 1, so the package will not match any of the rules. Thus, the packet will be dropped, so that from the side the result will be the same as in the first example.

Create a table 1: Processing VLANs at the entrance


The packets that arrive in Table 1 have already passed all the basic checks in Table 0. Table 1 is for attaching packets to VLANs. The check is based on a comparison of the VLAN and the port through which the packets enter the switch. We will also use the table to attach the VLAN header to the packet that goes to the aggregation port, which will allow postponing the processing stages related to the VLAN, since the VLAN number will always be part of the header (except in special cases).

Start by adding a low priority rule that will drop all packets. Before it, we add rules that let us pass the packets we need. Let it be a “drop by default” rule.

 $ ovs-ofctl add-flow br0 "table=1, priority=0, actions=drop" 

The p1 aggregation port (or OpenFlow port 1, which is simpler) accepts any packets, regardless of whether they have a VLAN header or not, and what the header is. Thus, we can add a rule that redirects all traffic from port 1 to the following table:

 $ ovs-ofctl add-flow br0 "table=1, priority=99, in_port=1, actions=resubmit(,2)" 

On access ports, we can receive any packets without a VLAN header, assign them the appropriate VLAN and transfer them to the next step.

 $ ovs-ofctl add-flows br0 - <<'EOF' table=1, priority=99, in_port=2, vlan_tci=0, actions=mod_vlan_vid:20, resubmit(,2) table=1, priority=99, in_port=3, vlan_tci=0, actions=mod_vlan_vid:30, resubmit(,2) table=1, priority=99, in_port=4, vlan_tci=0, actions=mod_vlan_vid:30, resubmit(,2) EOF 

We will not write the rules. processing packets with existing VLAN tags (802.1Q) that arrive at access ports, so these packets will be discarded by the default rule. This is the behavior we expect from access ports.

In other cases, access ports pass packets belonging to VLAN 0 (that is, packets marked according to the 802.1p traffic prioritization mechanism). To allow such packages, replace vlan_tci = 0 with vlan_tci = 0 / 0xfff in the rule above.

Testing table 1


The utility ofproto / trace allows us to check the added rules for managing VLANs at the entrance to the switch.

Example 1. Package on an aggregation port


Checking the packet that came to the switch from the aggregation port:

 $ ovs-appctl ofproto/trace br0 in_port=1,vlan_tci=5 

From the output of the command, it follows that the packet passes table 0, is sent to table 1, and then to table 2 (in which there are no rules yet).

 Bridge: br0 Flow: in_port=1,vlan_tci=0x0005,dl_src=00:00:00:00:00:00,dl_dst=00:00:00:00:00:00,dl_type=0x0000 Rule: table=0 cookie=0 priority=0 OpenFlow actions=resubmit(,1) Resubmitted flow: in_port=1,vlan_tci=0x0005,dl_src=00:00:00:00:00:00,dl_dst=00:00:00:00:00:00,dl_type=0x0000 Resubmitted regs: reg0=0x0 reg1=0x0 reg2=0x0 reg3=0x0 reg4=0x0 reg5=0x0 reg6=0x0 reg7=0x0 reg8=0x0 reg9=0x0 reg10=0x0 reg11=0x0 reg12=0x0 reg13=0x0 reg14=0x0 reg15=0x0 Resubmitted odp: drop Resubmitted megaflow: recirc_id=0,in_port=1,dl_src=00:00:00:00:00:00/01:00:00:00:00:00,dl_dst=00:00:00:00:00:00/ff:ff:ff:ff:ff:f0,dl_type=0x0000 Rule: table=1 cookie=0 priority=99,in_port=1 OpenFlow actions=resubmit(,2) Resubmitted flow: unchanged Resubmitted regs: reg0=0x0 reg1=0x0 reg2=0x0 reg3=0x0 reg4=0x0 reg5=0x0 reg6=0x0 reg7=0x0 reg8=0x0 reg9=0x0 reg10=0x0 reg11=0x0 reg12=0x0 reg13=0x0 reg14=0x0 reg15=0x0 Resubmitted odp: drop Resubmitted megaflow: recirc_id=0,in_port=1,dl_src=00:00:00:00:00:00/01:00:00:00:00:00,dl_dst=00:00:00:00:00:00/ff:ff:ff:ff:ff:f0,dl_type=0x0000 Rule: table=254 cookie=0 priority=0,reg0=0x2 OpenFlow actions=drop Final flow: unchanged Megaflow: recirc_id=0,in_port=1,dl_src=00:00:00:00:00:00/01:00:00:00:00:00,dl_dst=00:00:00:00:00:00/ff:ff:ff:ff:ff:f0,dl_type=0x0000 Datapath actions: drop 0x0 reg2 = 0x0 reg3 = 0x0 reg4 = 0x0 reg5 = 0x0 reg6 = 0x0 reg7 = 0x0 reg8 = 0x0 reg9 = 0x0 reg10 = 0x0 reg11 = 0x0 reg12 = 0x0 reg13 = 0x0 reg14 = 0x0 reg15 = Bridge: br0 Flow: in_port=1,vlan_tci=0x0005,dl_src=00:00:00:00:00:00,dl_dst=00:00:00:00:00:00,dl_type=0x0000 Rule: table=0 cookie=0 priority=0 OpenFlow actions=resubmit(,1) Resubmitted flow: in_port=1,vlan_tci=0x0005,dl_src=00:00:00:00:00:00,dl_dst=00:00:00:00:00:00,dl_type=0x0000 Resubmitted regs: reg0=0x0 reg1=0x0 reg2=0x0 reg3=0x0 reg4=0x0 reg5=0x0 reg6=0x0 reg7=0x0 reg8=0x0 reg9=0x0 reg10=0x0 reg11=0x0 reg12=0x0 reg13=0x0 reg14=0x0 reg15=0x0 Resubmitted odp: drop Resubmitted megaflow: recirc_id=0,in_port=1,dl_src=00:00:00:00:00:00/01:00:00:00:00:00,dl_dst=00:00:00:00:00:00/ff:ff:ff:ff:ff:f0,dl_type=0x0000 Rule: table=1 cookie=0 priority=99,in_port=1 OpenFlow actions=resubmit(,2) Resubmitted flow: unchanged Resubmitted regs: reg0=0x0 reg1=0x0 reg2=0x0 reg3=0x0 reg4=0x0 reg5=0x0 reg6=0x0 reg7=0x0 reg8=0x0 reg9=0x0 reg10=0x0 reg11=0x0 reg12=0x0 reg13=0x0 reg14=0x0 reg15=0x0 Resubmitted odp: drop Resubmitted megaflow: recirc_id=0,in_port=1,dl_src=00:00:00:00:00:00/01:00:00:00:00:00,dl_dst=00:00:00:00:00:00/ff:ff:ff:ff:ff:f0,dl_type=0x0000 Rule: table=254 cookie=0 priority=0,reg0=0x2 OpenFlow actions=drop Final flow: unchanged Megaflow: recirc_id=0,in_port=1,dl_src=00:00:00:00:00:00/01:00:00:00:00:00,dl_dst=00:00:00:00:00:00/ff:ff:ff:ff:ff:f0,dl_type=0x0000 Datapath actions: drop 0x0 reg2 = 0x0 reg3 = 0x0 reg4 = 0x0 reg5 = 0x0 reg6 = 0x0 reg7 = 0x0 reg8 = 0x0 reg9 = 0x0 reg10 = 0x0 reg11 = 0x0 reg12 = 0x0 reg13 = 0x0 reg14 = 0x0 reg15 = Bridge: br0 Flow: in_port=1,vlan_tci=0x0005,dl_src=00:00:00:00:00:00,dl_dst=00:00:00:00:00:00,dl_type=0x0000 Rule: table=0 cookie=0 priority=0 OpenFlow actions=resubmit(,1) Resubmitted flow: in_port=1,vlan_tci=0x0005,dl_src=00:00:00:00:00:00,dl_dst=00:00:00:00:00:00,dl_type=0x0000 Resubmitted regs: reg0=0x0 reg1=0x0 reg2=0x0 reg3=0x0 reg4=0x0 reg5=0x0 reg6=0x0 reg7=0x0 reg8=0x0 reg9=0x0 reg10=0x0 reg11=0x0 reg12=0x0 reg13=0x0 reg14=0x0 reg15=0x0 Resubmitted odp: drop Resubmitted megaflow: recirc_id=0,in_port=1,dl_src=00:00:00:00:00:00/01:00:00:00:00:00,dl_dst=00:00:00:00:00:00/ff:ff:ff:ff:ff:f0,dl_type=0x0000 Rule: table=1 cookie=0 priority=99,in_port=1 OpenFlow actions=resubmit(,2) Resubmitted flow: unchanged Resubmitted regs: reg0=0x0 reg1=0x0 reg2=0x0 reg3=0x0 reg4=0x0 reg5=0x0 reg6=0x0 reg7=0x0 reg8=0x0 reg9=0x0 reg10=0x0 reg11=0x0 reg12=0x0 reg13=0x0 reg14=0x0 reg15=0x0 Resubmitted odp: drop Resubmitted megaflow: recirc_id=0,in_port=1,dl_src=00:00:00:00:00:00/01:00:00:00:00:00,dl_dst=00:00:00:00:00:00/ff:ff:ff:ff:ff:f0,dl_type=0x0000 Rule: table=254 cookie=0 priority=0,reg0=0x2 OpenFlow actions=drop Final flow: unchanged Megaflow: recirc_id=0,in_port=1,dl_src=00:00:00:00:00:00/01:00:00:00:00:00,dl_dst=00:00:00:00:00:00/ff:ff:ff:ff:ff:f0,dl_type=0x0000 Datapath actions: drop 

Example 2. Correct packet on the access port


We are testing the correct packet (i.e., a packet without the 802.1Q header) coming on port p2:

 $ ovs-appctl ofproto/trace br0 in_port=2 

The output of this command is similar to the output of the previous one, except that a packet is assigned a VLAN tag 20 before being sent to Table 2.

 Bridge: br0 Flow: in_port=2,vlan_tci=0x0000,dl_src=00:00:00:00:00:00,dl_dst=00:00:00:00:00:00,dl_type=0x0000 Rule: table=0 cookie=0 priority=0 OpenFlow actions=resubmit(,1) Resubmitted flow: in_port=2,vlan_tci=0x0000,dl_src=00:00:00:00:00:00,dl_dst=00:00:00:00:00:00,dl_type=0x0000 Resubmitted regs: reg0=0x0 reg1=0x0 reg2=0x0 reg3=0x0 reg4=0x0 reg5=0x0 reg6=0x0 reg7=0x0 reg8=0x0 reg9=0x0 reg10=0x0 reg11=0x0 reg12=0x0 reg13=0x0 reg14=0x0 reg15=0x0 Resubmitted odp: drop Resubmitted megaflow: recirc_id=0,in_port=2,vlan_tci=0x0000,dl_src=00:00:00:00:00:00/01:00:00:00:00:00,dl_dst=00:00:00:00:00:00/ff:ff:ff:ff:ff:f0,dl_type=0x0000 Rule: table=1 cookie=0 priority=99,in_port=2,vlan_tci=0x0000 OpenFlow actions=mod_vlan_vid:20,resubmit(,2) Resubmitted flow: in_port=2,dl_vlan=20,dl_vlan_pcp=0,dl_src=00:00:00:00:00:00,dl_dst=00:00:00:00:00:00,dl_type=0x0000 Resubmitted regs: reg0=0x0 reg1=0x0 reg2=0x0 reg3=0x0 reg4=0x0 reg5=0x0 reg6=0x0 reg7=0x0 reg8=0x0 reg9=0x0 reg10=0x0 reg11=0x0 reg12=0x0 reg13=0x0 reg14=0x0 reg15=0x0 Resubmitted odp: drop Resubmitted megaflow: recirc_id=0,in_port=2,vlan_tci=0x0000,dl_src=00:00:00:00:00:00/01:00:00:00:00:00,dl_dst=00:00:00:00:00:00/ff:ff:ff:ff:ff:f0,dl_type=0x0000 Rule: table=254 cookie=0 priority=0,reg0=0x2 OpenFlow actions=drop Final flow: in_port=2,dl_vlan=20,dl_vlan_pcp=0,dl_src=00:00:00:00:00:00,dl_dst=00:00:00:00:00:00,dl_type=0x0000 Megaflow: recirc_id=0,in_port=2,vlan_tci=0x0000,dl_src=00:00:00:00:00:00/01:00:00:00:00:00,dl_dst=00:00:00:00:00:00/ff:ff:ff:ff:ff:f0,dl_type=0x0000 Datapath actions: drop 0x0 reg2 = 0x0 reg3 = 0x0 reg4 = 0x0 reg5 = 0x0 reg6 = 0x0 reg7 = 0x0 reg8 = 0x0 reg9 = 0x0 reg10 = 0x0 reg11 = 0x0 reg12 = 0x0 reg13 = 0x0 reg14 = 0x0 reg15 = Bridge: br0 Flow: in_port=2,vlan_tci=0x0000,dl_src=00:00:00:00:00:00,dl_dst=00:00:00:00:00:00,dl_type=0x0000 Rule: table=0 cookie=0 priority=0 OpenFlow actions=resubmit(,1) Resubmitted flow: in_port=2,vlan_tci=0x0000,dl_src=00:00:00:00:00:00,dl_dst=00:00:00:00:00:00,dl_type=0x0000 Resubmitted regs: reg0=0x0 reg1=0x0 reg2=0x0 reg3=0x0 reg4=0x0 reg5=0x0 reg6=0x0 reg7=0x0 reg8=0x0 reg9=0x0 reg10=0x0 reg11=0x0 reg12=0x0 reg13=0x0 reg14=0x0 reg15=0x0 Resubmitted odp: drop Resubmitted megaflow: recirc_id=0,in_port=2,vlan_tci=0x0000,dl_src=00:00:00:00:00:00/01:00:00:00:00:00,dl_dst=00:00:00:00:00:00/ff:ff:ff:ff:ff:f0,dl_type=0x0000 Rule: table=1 cookie=0 priority=99,in_port=2,vlan_tci=0x0000 OpenFlow actions=mod_vlan_vid:20,resubmit(,2) Resubmitted flow: in_port=2,dl_vlan=20,dl_vlan_pcp=0,dl_src=00:00:00:00:00:00,dl_dst=00:00:00:00:00:00,dl_type=0x0000 Resubmitted regs: reg0=0x0 reg1=0x0 reg2=0x0 reg3=0x0 reg4=0x0 reg5=0x0 reg6=0x0 reg7=0x0 reg8=0x0 reg9=0x0 reg10=0x0 reg11=0x0 reg12=0x0 reg13=0x0 reg14=0x0 reg15=0x0 Resubmitted odp: drop Resubmitted megaflow: recirc_id=0,in_port=2,vlan_tci=0x0000,dl_src=00:00:00:00:00:00/01:00:00:00:00:00,dl_dst=00:00:00:00:00:00/ff:ff:ff:ff:ff:f0,dl_type=0x0000 Rule: table=254 cookie=0 priority=0,reg0=0x2 OpenFlow actions=drop Final flow: in_port=2,dl_vlan=20,dl_vlan_pcp=0,dl_src=00:00:00:00:00:00,dl_dst=00:00:00:00:00:00,dl_type=0x0000 Megaflow: recirc_id=0,in_port=2,vlan_tci=0x0000,dl_src=00:00:00:00:00:00/01:00:00:00:00:00,dl_dst=00:00:00:00:00:00/ff:ff:ff:ff:ff:f0,dl_type=0x0000 Datapath actions: drop 0x0 reg2 = 0x0 reg3 = 0x0 reg4 = 0x0 reg5 = 0x0 reg6 = 0x0 reg7 = 0x0 reg8 = 0x0 reg9 = 0x0 reg10 = 0x0 reg11 = 0x0 reg12 = 0x0 reg13 = 0x0 reg14 = 0x0 reg15 = Bridge: br0 Flow: in_port=2,vlan_tci=0x0000,dl_src=00:00:00:00:00:00,dl_dst=00:00:00:00:00:00,dl_type=0x0000 Rule: table=0 cookie=0 priority=0 OpenFlow actions=resubmit(,1) Resubmitted flow: in_port=2,vlan_tci=0x0000,dl_src=00:00:00:00:00:00,dl_dst=00:00:00:00:00:00,dl_type=0x0000 Resubmitted regs: reg0=0x0 reg1=0x0 reg2=0x0 reg3=0x0 reg4=0x0 reg5=0x0 reg6=0x0 reg7=0x0 reg8=0x0 reg9=0x0 reg10=0x0 reg11=0x0 reg12=0x0 reg13=0x0 reg14=0x0 reg15=0x0 Resubmitted odp: drop Resubmitted megaflow: recirc_id=0,in_port=2,vlan_tci=0x0000,dl_src=00:00:00:00:00:00/01:00:00:00:00:00,dl_dst=00:00:00:00:00:00/ff:ff:ff:ff:ff:f0,dl_type=0x0000 Rule: table=1 cookie=0 priority=99,in_port=2,vlan_tci=0x0000 OpenFlow actions=mod_vlan_vid:20,resubmit(,2) Resubmitted flow: in_port=2,dl_vlan=20,dl_vlan_pcp=0,dl_src=00:00:00:00:00:00,dl_dst=00:00:00:00:00:00,dl_type=0x0000 Resubmitted regs: reg0=0x0 reg1=0x0 reg2=0x0 reg3=0x0 reg4=0x0 reg5=0x0 reg6=0x0 reg7=0x0 reg8=0x0 reg9=0x0 reg10=0x0 reg11=0x0 reg12=0x0 reg13=0x0 reg14=0x0 reg15=0x0 Resubmitted odp: drop Resubmitted megaflow: recirc_id=0,in_port=2,vlan_tci=0x0000,dl_src=00:00:00:00:00:00/01:00:00:00:00:00,dl_dst=00:00:00:00:00:00/ff:ff:ff:ff:ff:f0,dl_type=0x0000 Rule: table=254 cookie=0 priority=0,reg0=0x2 OpenFlow actions=drop Final flow: in_port=2,dl_vlan=20,dl_vlan_pcp=0,dl_src=00:00:00:00:00:00,dl_dst=00:00:00:00:00:00,dl_type=0x0000 Megaflow: recirc_id=0,in_port=2,vlan_tci=0x0000,dl_src=00:00:00:00:00:00/01:00:00:00:00:00,dl_dst=00:00:00:00:00:00/ff:ff:ff:ff:ff:f0,dl_type=0x0000 Datapath actions: drop 

Example 3. Invalid packet (with header 801.2Q) on port p2


 $ ovs-appctl ofproto/trace br0 in_port=2,vlan_tci=5 

The output of the command shows that the packet arrives in table 1 and is discarded by the default rule.

 Bridge: br0 Flow: in_port=2,vlan_tci=0x0005,dl_src=00:00:00:00:00:00,dl_dst=00:00:00:00:00:00,dl_type=0x0000 Rule: table=0 cookie=0 priority=0 OpenFlow actions=resubmit(,1) Resubmitted flow: in_port=2,vlan_tci=0x0005,dl_src=00:00:00:00:00:00,dl_dst=00:00:00:00:00:00,dl_type=0x0000 Resubmitted regs: reg0=0x0 reg1=0x0 reg2=0x0 reg3=0x0 reg4=0x0 reg5=0x0 reg6=0x0 reg7=0x0 reg8=0x0 reg9=0x0 reg10=0x0 reg11=0x0 reg12=0x0 reg13=0x0 reg14=0x0 reg15=0x0 Resubmitted odp: drop Resubmitted megaflow: recirc_id=0,in_port=2,vlan_tci=0x0005,dl_src=00:00:00:00:00:00/01:00:00:00:00:00,dl_dst=00:00:00:00:00:00/ff:ff:ff:ff:ff:f0,dl_type=0x0000 Rule: table=1 cookie=0 priority=0 OpenFlow actions=drop Final flow: unchanged Megaflow: recirc_id=0,in_port=2,vlan_tci=0x0005,dl_src=00:00:00:00:00:00/01:00:00:00:00:00,dl_dst=00:00:00:00:00:00/ff:ff:ff:ff:ff:f0,dl_type=0x0000 Datapath actions: drop 0x0 reg2 = 0x0 reg3 = 0x0 reg4 = 0x0 reg5 = 0x0 reg6 = 0x0 reg7 = 0x0 reg8 = 0x0 reg9 = 0x0 reg10 = 0x0 reg11 = 0x0 reg12 = 0x0 reg13 = 0x0 reg14 = 0x0 reg15 = Bridge: br0 Flow: in_port=2,vlan_tci=0x0005,dl_src=00:00:00:00:00:00,dl_dst=00:00:00:00:00:00,dl_type=0x0000 Rule: table=0 cookie=0 priority=0 OpenFlow actions=resubmit(,1) Resubmitted flow: in_port=2,vlan_tci=0x0005,dl_src=00:00:00:00:00:00,dl_dst=00:00:00:00:00:00,dl_type=0x0000 Resubmitted regs: reg0=0x0 reg1=0x0 reg2=0x0 reg3=0x0 reg4=0x0 reg5=0x0 reg6=0x0 reg7=0x0 reg8=0x0 reg9=0x0 reg10=0x0 reg11=0x0 reg12=0x0 reg13=0x0 reg14=0x0 reg15=0x0 Resubmitted odp: drop Resubmitted megaflow: recirc_id=0,in_port=2,vlan_tci=0x0005,dl_src=00:00:00:00:00:00/01:00:00:00:00:00,dl_dst=00:00:00:00:00:00/ff:ff:ff:ff:ff:f0,dl_type=0x0000 Rule: table=1 cookie=0 priority=0 OpenFlow actions=drop Final flow: unchanged Megaflow: recirc_id=0,in_port=2,vlan_tci=0x0005,dl_src=00:00:00:00:00:00/01:00:00:00:00:00,dl_dst=00:00:00:00:00:00/ff:ff:ff:ff:ff:f0,dl_type=0x0000 Datapath actions: drop 

Create table 2: remember the MAC + VLAN pair on the incoming port


Table 2 allows the switch to remember which sender MAC address matches the specified port and packet VLAN tag.

This table is a good illustration of why VLAN tags are added to packets that come to the switch through the access port, specifically in Table 1. We want to match a pair of VLAN + MAC with a port, regardless of whether the packet already belonged to VLAN when it came into the switch, or the VLAN tag was put in the packet by the switch itself.

It takes only one rule to realize our idea. Here it is:

 $ ovs-ofctl add-flow br0 \ "table=2 actions=learn(table=10, NXM_OF_VLAN_TCI[0..11], \ NXM_OF_ETH_DST[]=NXM_OF_ETH_SRC[], \ load:NXM_OF_IN_PORT[]->NXM_NX_REG0[0..15]), \ resubmit(,3)" 

The “learn” action changes the table with rules based on the contents of the package that is being processed at the moment. OpenFlow, Open vSwitch.

“learn” :

 table=10 

10. MAC-

 NXM_OF_VLAN_TCI[0..11] 

10, VLAN, VLAN . MAC VLAN, VLAN

 NXM_OF_ETH_DST[]=NXM_OF_ETH_SRC[] 

“MAC- ”, MAC- .

 load:NXM_OF_IN_PORT[]->NXM_NX_REG0[0..15] 
, , . , , 0 ( , Open vSwitch OpenFlow)
MAC- . -, “learn” hard_timeout , “” MAC-, . -, , 10 Flow_Table Open vSwitch.

,

2


1


:

 $ ovs-appctl ofproto/trace br0 in_port=1,vlan_tci=20,dl_src=50:00:00:00:00:01 -generate 

, “learn” 10 .

 Bridge: br0 Flow: in_port=1,vlan_tci=0x0014,dl_src=50:00:00:00:00:01,dl_dst=00:00:00:00:00:00,dl_type=0x0000 Rule: table=0 cookie=0 priority=0 OpenFlow actions=resubmit(,1) Resubmitted flow: in_port=1,vlan_tci=0x0014,dl_src=50:00:00:00:00:01,dl_dst=00:00:00:00:00:00,dl_type=0x0000 Resubmitted regs: reg0=0x0 reg1=0x0 reg2=0x0 reg3=0x0 reg4=0x0 reg5=0x0 reg6=0x0 reg7=0x0 reg8=0x0 reg9=0x0 reg10=0x0 reg11=0x0 reg12=0x0 reg13=0x0 reg14=0x0 reg15=0x0 Resubmitted odp: drop Resubmitted megaflow: recirc_id=0,in_port=1,dl_src=00:00:00:00:00:00/01:00:00:00:00:00,dl_dst=00:00:00:00:00:00/ff:ff:ff:ff:ff:f0,dl_type=0x0000 Rule: table=1 cookie=0 priority=99,in_port=1 OpenFlow actions=resubmit(,2) Resubmitted flow: unchanged Resubmitted regs: reg0=0x0 reg1=0x0 reg2=0x0 reg3=0x0 reg4=0x0 reg5=0x0 reg6=0x0 reg7=0x0 reg8=0x0 reg9=0x0 reg10=0x0 reg11=0x0 reg12=0x0 reg13=0x0 reg14=0x0 reg15=0x0 Resubmitted odp: drop Resubmitted megaflow: recirc_id=0,in_port=1,dl_src=00:00:00:00:00:00/01:00:00:00:00:00,dl_dst=00:00:00:00:00:00/ff:ff:ff:ff:ff:f0,dl_type=0x0000 Rule: table=2 cookie=0 OpenFlow actions=learn(table=10,NXM_OF_VLAN_TCI[0..11],NXM_OF_ETH_DST[]=NXM_OF_ETH_SRC[],load:NXM_OF_IN_PORT[]->NXM_NX_REG0[0..15]),resubmit(,3) Resubmitted flow: unchanged Resubmitted regs: reg0=0x0 reg1=0x0 reg2=0x0 reg3=0x0 reg4=0x0 reg5=0x0 reg6=0x0 reg7=0x0 reg8=0x0 reg9=0x0 reg10=0x0 reg11=0x0 reg12=0x0 reg13=0x0 reg14=0x0 reg15=0x0 Resubmitted odp: drop Resubmitted megaflow: recirc_id=0,in_port=1,vlan_tci=0x0014/0x0fff,dl_src=50:00:00:00:00:01,dl_dst=00:00:00:00:00:00/ff:ff:ff:ff:ff:f0,dl_type=0x0000 Rule: table=254 cookie=0 priority=0,reg0=0x2 OpenFlow actions=drop Final flow: unchanged Megaflow: recirc_id=0,in_port=1,vlan_tci=0x0014/0x1fff,dl_src=50:00:00:00:00:01,dl_dst=00:00:00:00:00:00/ff:ff:ff:ff:ff:f0,dl_type=0x0000 Datapath actions: drop 

-generate. , ofproto/trace : “output” , “learn” . -generate ofproto/trace “learn”. , “learn” 10.

:

 $ ovs-ofctl dump-flows br0 table=10 

:

 NXST_FLOW reply (xid=0x4): cookie=0x0, duration=4315.181s, table=10, n_packets=0, n_bytes=0, idle_age=4315, vlan_tci=0x0014/0x0fff,dl_dst=50:00:00:00:00:01 actions=load:0x1->NXM_NX_REG0[0..15] 

, VLAN 20 50:00:00:00:00:01 , VLAN 20 50:00:00:00:00:01. 1, , 0.

2


:

 $ ovs-appctl ofproto/trace br0 in_port=2,dl_src=50:00:00:00:00:01 -generate 

 Bridge: br0 Flow: in_port=2,vlan_tci=0x0000,dl_src=50:00:00:00:00:01,dl_dst=00:00:00:00:00:00,dl_type=0x0000 Rule: table=0 cookie=0 priority=0 OpenFlow actions=resubmit(,1) Resubmitted flow: in_port=2,vlan_tci=0x0000,dl_src=50:00:00:00:00:01,dl_dst=00:00:00:00:00:00,dl_type=0x0000 Resubmitted regs: reg0=0x0 reg1=0x0 reg2=0x0 reg3=0x0 reg4=0x0 reg5=0x0 reg6=0x0 reg7=0x0 reg8=0x0 reg9=0x0 reg10=0x0 reg11=0x0 reg12=0x0 reg13=0x0 reg14=0x0 reg15=0x0 Resubmitted odp: drop Resubmitted megaflow: recirc_id=0,in_port=2,vlan_tci=0x0000,dl_src=00:00:00:00:00:00/01:00:00:00:00:00,dl_dst=00:00:00:00:00:00/ff:ff:ff:ff:ff:f0,dl_type=0x0000 Rule: table=1 cookie=0 priority=99,in_port=2,vlan_tci=0x0000 OpenFlow actions=mod_vlan_vid:20,resubmit(,2) Resubmitted flow: in_port=2,dl_vlan=20,dl_vlan_pcp=0,dl_src=50:00:00:00:00:01,dl_dst=00:00:00:00:00:00,dl_type=0x0000 Resubmitted regs: reg0=0x0 reg1=0x0 reg2=0x0 reg3=0x0 reg4=0x0 reg5=0x0 reg6=0x0 reg7=0x0 reg8=0x0 reg9=0x0 reg10=0x0 reg11=0x0 reg12=0x0 reg13=0x0 reg14=0x0 reg15=0x0 Resubmitted odp: drop Resubmitted megaflow: recirc_id=0,in_port=2,vlan_tci=0x0000,dl_src=00:00:00:00:00:00/01:00:00:00:00:00,dl_dst=00:00:00:00:00:00/ff:ff:ff:ff:ff:f0,dl_type=0x0000 Rule: table=2 cookie=0 OpenFlow actions=learn(table=10,NXM_OF_VLAN_TCI[0..11],NXM_OF_ETH_DST[]=NXM_OF_ETH_SRC[],load:NXM_OF_IN_PORT[]->NXM_NX_REG0[0..15]),resubmit(,3) Resubmitted flow: unchanged Resubmitted regs: reg0=0x0 reg1=0x0 reg2=0x0 reg3=0x0 reg4=0x0 reg5=0x0 reg6=0x0 reg7=0x0 reg8=0x0 reg9=0x0 reg10=0x0 reg11=0x0 reg12=0x0 reg13=0x0 reg14=0x0 reg15=0x0 Resubmitted odp: drop Resubmitted megaflow: recirc_id=0,in_port=2,vlan_tci=0x0000,dl_src=50:00:00:00:00:01,dl_dst=00:00:00:00:00:00/ff:ff:ff:ff:ff:f0,dl_type=0x0000 Rule: table=254 cookie=0 priority=0,reg0=0x2 OpenFlow actions=drop Final flow: in_port=2,dl_vlan=20,dl_vlan_pcp=0,dl_src=50:00:00:00:00:01,dl_dst=00:00:00:00:00:00,dl_type=0x0000 Megaflow: recirc_id=0,in_port=2,vlan_tci=0x0000,dl_src=50:00:00:00:00:01,dl_dst=00:00:00:00:00:00/ff:ff:ff:ff:ff:f0,dl_type=0x0000 Datapath actions: drop 

, , VLAN MAC, , VLAN. 802.1Q. 10

 $ ovs-ofctl dump-flows br0 table=10 NXST_FLOW reply (xid=0x4): cookie=0x0, duration=4355.977s, table=10, n_packets=0, n_bytes=0, idle_age=4355, hard_age=15, vlan_tci=0x0014/0x0fff,dl_dst=50:00:00:00:00:01 actions=load:0x2->NXM_NX_REG0[0..15] 

, , , 2. .

3:


, , MAC- VLAN. 2 , .



 $ ovs-ofctl add-flow br0 "table=3 priority=50 actions=resubmit(,10), resubmit(,4)" 

10, “learn”. , 0. , 10 , “resubmit” . , 0 №0 , .

— 4, .

, 10 , .

 $ ovs-ofctl add-flow br0 "table=3 priority=99 dl_dst=01:00:00:00:00:00/01:00:00:00:00:00 actions=resubmit(,4)" 

, 10, 0 , .


3


Example


, Open vSwitch f0:00:00:00:00:01 p1 VLAN' 20:

 $ ovs-appctl ofproto/trace br0 in_port=1,dl_vlan=20,dl_src=f0:00:00:00:00:01,dl_dst=90:00:00:00:00:01 -generate 

, , 10 .

 Bridge: br0 Flow: in_port=1,dl_vlan=20,dl_vlan_pcp=0,dl_src=f0:00:00:00:00:01,dl_dst=90:00:00:00:00:01,dl_type=0x0000 Rule: table=0 cookie=0 priority=0 OpenFlow actions=resubmit(,1) Resubmitted flow: in_port=1,dl_vlan=20,dl_vlan_pcp=0,dl_src=f0:00:00:00:00:01,dl_dst=90:00:00:00:00:01,dl_type=0x0000 Resubmitted regs: reg0=0x0 reg1=0x0 reg2=0x0 reg3=0x0 reg4=0x0 reg5=0x0 reg6=0x0 reg7=0x0 reg8=0x0 reg9=0x0 reg10=0x0 reg11=0x0 reg12=0x0 reg13=0x0 reg14=0x0 reg15=0x0 Resubmitted odp: drop Resubmitted megaflow: recirc_id=0,in_port=1,dl_src=00:00:00:00:00:00/01:00:00:00:00:00,dl_dst=90:00:00:00:00:00/ff:ff:ff:ff:ff:f0,dl_type=0x0000 Rule: table=1 cookie=0 priority=99,in_port=1 OpenFlow actions=resubmit(,2) Resubmitted flow: unchanged Resubmitted regs: reg0=0x0 reg1=0x0 reg2=0x0 reg3=0x0 reg4=0x0 reg5=0x0 reg6=0x0 reg7=0x0 reg8=0x0 reg9=0x0 reg10=0x0 reg11=0x0 reg12=0x0 reg13=0x0 reg14=0x0 reg15=0x0 Resubmitted odp: drop Resubmitted megaflow: recirc_id=0,in_port=1,dl_src=00:00:00:00:00:00/01:00:00:00:00:00,dl_dst=90:00:00:00:00:00/ff:ff:ff:ff:ff:f0,dl_type=0x0000 Rule: table=2 cookie=0 OpenFlow actions=learn(table=10,NXM_OF_VLAN_TCI[0..11],NXM_OF_ETH_DST[]=NXM_OF_ETH_SRC[],load:NXM_OF_IN_PORT[]->NXM_NX_REG0[0..15]),resubmit(,3) Resubmitted flow: unchanged Resubmitted regs: reg0=0x0 reg1=0x0 reg2=0x0 reg3=0x0 reg4=0x0 reg5=0x0 reg6=0x0 reg7=0x0 reg8=0x0 reg9=0x0 reg10=0x0 reg11=0x0 reg12=0x0 reg13=0x0 reg14=0x0 reg15=0x0 Resubmitted odp: drop Resubmitted megaflow: recirc_id=0,in_port=1,vlan_tci=0x0014/0x0fff,dl_src=f0:00:00:00:00:01,dl_dst=90:00:00:00:00:00/ff:ff:ff:ff:ff:f0,dl_type=0x0000 Rule: table=3 cookie=0 priority=50 OpenFlow actions=resubmit(,10),resubmit(,4) Resubmitted flow: unchanged Resubmitted regs: reg0=0x0 reg1=0x0 reg2=0x0 reg3=0x0 reg4=0x0 reg5=0x0 reg6=0x0 reg7=0x0 reg8=0x0 reg9=0x0 reg10=0x0 reg11=0x0 reg12=0x0 reg13=0x0 reg14=0x0 reg15=0x0 Resubmitted odp: drop Resubmitted megaflow: recirc_id=0,in_port=1,vlan_tci=0x0014/0x0fff,dl_src=f0:00:00:00:00:01,dl_dst=90:00:00:00:00:01,dl_type=0x0000 Rule: table=254 cookie=0 priority=0,reg0=0x2 OpenFlow actions=drop Resubmitted flow: unchanged Resubmitted regs: reg0=0x0 reg1=0x0 reg2=0x0 reg3=0x0 reg4=0x0 reg5=0x0 reg6=0x0 reg7=0x0 reg8=0x0 reg9=0x0 reg10=0x0 reg11=0x0 reg12=0x0 reg13=0x0 reg14=0x0 reg15=0x0 Resubmitted odp: drop Resubmitted megaflow: recirc_id=0,in_port=1,vlan_tci=0x0014/0x0fff,dl_src=f0:00:00:00:00:01,dl_dst=90:00:00:00:00:01,dl_type=0x0000 Rule: table=254 cookie=0 priority=0,reg0=0x2 OpenFlow actions=drop Final flow: unchanged Megaflow: recirc_id=0,in_port=1,dl_vlan=20,dl_src=f0:00:00:00:00:01,dl_dst=90:00:00:00:00:01,dl_type=0x0000 Datapath actions: drop 

, . — 10 :

 $ ovs-ofctl dump-flows br0 table=10 

:

 NXST_FLOW reply (xid=0x4): cookie=0x0, duration=54.661s, table=10, n_packets=0, n_bytes=0, idle_age=54, vlan_tci=0x0014/0x0fff,dl_dst=f0:00:00:00:00:01 actions=load:0x1->NXM_NX_REG0[0..15] 

, , . , , ovs-ofctl del-flows br0 table=10

— , . , p2, p1.

 $ ovs-appctl ofproto/trace br0 in_port=2,dl_src=90:00:00:00:00:01,dl_dst=f0:00:00:00:00:01 -generate 

. , “resubmit(,10)”. , , MAC-, , p1 0.

 Bridge: br0 Flow: in_port=2,vlan_tci=0x0000,dl_src=90:00:00:00:00:01,dl_dst=f0:00:00:00:00:01,dl_type=0x0000 Rule: table=0 cookie=0 priority=0 OpenFlow actions=resubmit(,1) Resubmitted flow: in_port=2,vlan_tci=0x0000,dl_src=90:00:00:00:00:01,dl_dst=f0:00:00:00:00:01,dl_type=0x0000 Resubmitted regs: reg0=0x0 reg1=0x0 reg2=0x0 reg3=0x0 reg4=0x0 reg5=0x0 reg6=0x0 reg7=0x0 reg8=0x0 reg9=0x0 reg10=0x0 reg11=0x0 reg12=0x0 reg13=0x0 reg14=0x0 reg15=0x0 Resubmitted odp: drop Resubmitted megaflow: recirc_id=0,in_port=2,vlan_tci=0x0000,dl_src=00:00:00:00:00:00/01:00:00:00:00:00,dl_dst=f0:00:00:00:00:00/ff:ff:ff:ff:ff:f0,dl_type=0x0000 Rule: table=1 cookie=0 priority=99,in_port=2,vlan_tci=0x0000 OpenFlow actions=mod_vlan_vid:20,resubmit(,2) Resubmitted flow: in_port=2,dl_vlan=20,dl_vlan_pcp=0,dl_src=90:00:00:00:00:01,dl_dst=f0:00:00:00:00:01,dl_type=0x0000 Resubmitted regs: reg0=0x0 reg1=0x0 reg2=0x0 reg3=0x0 reg4=0x0 reg5=0x0 reg6=0x0 reg7=0x0 reg8=0x0 reg9=0x0 reg10=0x0 reg11=0x0 reg12=0x0 reg13=0x0 reg14=0x0 reg15=0x0 Resubmitted odp: drop Resubmitted megaflow: recirc_id=0,in_port=2,vlan_tci=0x0000,dl_src=00:00:00:00:00:00/01:00:00:00:00:00,dl_dst=f0:00:00:00:00:00/ff:ff:ff:ff:ff:f0,dl_type=0x0000 Rule: table=2 cookie=0 OpenFlow actions=learn(table=10,NXM_OF_VLAN_TCI[0..11],NXM_OF_ETH_DST[]=NXM_OF_ETH_SRC[],load:NXM_OF_IN_PORT[]->NXM_NX_REG0[0..15]),resubmit(,3) Resubmitted flow: unchanged Resubmitted regs: reg0=0x0 reg1=0x0 reg2=0x0 reg3=0x0 reg4=0x0 reg5=0x0 reg6=0x0 reg7=0x0 reg8=0x0 reg9=0x0 reg10=0x0 reg11=0x0 reg12=0x0 reg13=0x0 reg14=0x0 reg15=0x0 Resubmitted odp: drop Resubmitted megaflow: recirc_id=0,in_port=2,vlan_tci=0x0000,dl_src=90:00:00:00:00:01,dl_dst=f0:00:00:00:00:00/ff:ff:ff:ff:ff:f0,dl_type=0x0000 Rule: table=3 cookie=0 priority=50 OpenFlow actions=resubmit(,10),resubmit(,4) Resubmitted flow: unchanged Resubmitted regs: reg0=0x0 reg1=0x0 reg2=0x0 reg3=0x0 reg4=0x0 reg5=0x0 reg6=0x0 reg7=0x0 reg8=0x0 reg9=0x0 reg10=0x0 reg11=0x0 reg12=0x0 reg13=0x0 reg14=0x0 reg15=0x0 Resubmitted odp: drop Resubmitted megaflow: recirc_id=0,in_port=2,vlan_tci=0x0000,dl_src=90:00:00:00:00:01,dl_dst=f0:00:00:00:00:01,dl_type=0x0000 Rule: table=10 cookie=0 vlan_tci=0x0014/0x0fff,dl_dst=f0:00:00:00:00:01 OpenFlow actions=load:0x1->NXM_NX_REG0[0..15] Resubmitted flow: reg0=0x1,in_port=2,dl_vlan=20,dl_vlan_pcp=0,dl_src=90:00:00:00:00:01,dl_dst=f0:00:00:00:00:01,dl_type=0x0000 Resubmitted regs: reg0=0x1 reg1=0x0 reg2=0x0 reg3=0x0 reg4=0x0 reg5=0x0 reg6=0x0 reg7=0x0 reg8=0x0 reg9=0x0 reg10=0x0 reg11=0x0 reg12=0x0 reg13=0x0 reg14=0x0 reg15=0x0 Resubmitted odp: drop Resubmitted megaflow: recirc_id=0,reg0=0/0xffff,in_port=2,vlan_tci=0x0000,dl_src=90:00:00:00:00:01,dl_dst=f0:00:00:00:00:01,dl_type=0x0000 Rule: table=254 cookie=0 priority=0,reg0=0x2 OpenFlow actions=drop Final flow: reg0=0x1,in_port=2,dl_vlan=20,dl_vlan_pcp=0,dl_src=90:00:00:00:00:01,dl_dst=f0:00:00:00:00:01,dl_type=0x0000 Megaflow: recirc_id=0,in_port=2,vlan_tci=0x0000,dl_src=90:00:00:00:00:01,dl_dst=f0:00:00:00:00:01,dl_type=0x0000 Datapath actions: drop 

, , , MAC- . , ovs-appctl

 $ ovs-appctl ofproto/trace br0 in_port=1,dl_vlan=20,dl_src=f0:00:00:00:00:01,dl_dst=90:00:00:00:00:01 -generate 

, “load” 10 :

 Bridge: br0 Flow: in_port=1,dl_vlan=20,dl_vlan_pcp=0,dl_src=f0:00:00:00:00:01,dl_dst=90:00:00:00:00:01,dl_type=0x0000 Rule: table=0 cookie=0 priority=0 OpenFlow actions=resubmit(,1) Resubmitted flow: in_port=1,dl_vlan=20,dl_vlan_pcp=0,dl_src=f0:00:00:00:00:01,dl_dst=90:00:00:00:00:01,dl_type=0x0000 Resubmitted regs: reg0=0x0 reg1=0x0 reg2=0x0 reg3=0x0 reg4=0x0 reg5=0x0 reg6=0x0 reg7=0x0 reg8=0x0 reg9=0x0 reg10=0x0 reg11=0x0 reg12=0x0 reg13=0x0 reg14=0x0 reg15=0x0 Resubmitted odp: drop Resubmitted megaflow: recirc_id=0,in_port=1,dl_src=00:00:00:00:00:00/01:00:00:00:00:00,dl_dst=90:00:00:00:00:00/ff:ff:ff:ff:ff:f0,dl_type=0x0000 Rule: table=1 cookie=0 priority=99,in_port=1 OpenFlow actions=resubmit(,2) Resubmitted flow: unchanged Resubmitted regs: reg0=0x0 reg1=0x0 reg2=0x0 reg3=0x0 reg4=0x0 reg5=0x0 reg6=0x0 reg7=0x0 reg8=0x0 reg9=0x0 reg10=0x0 reg11=0x0 reg12=0x0 reg13=0x0 reg14=0x0 reg15=0x0 Resubmitted odp: drop Resubmitted megaflow: recirc_id=0,in_port=1,dl_src=00:00:00:00:00:00/01:00:00:00:00:00,dl_dst=90:00:00:00:00:00/ff:ff:ff:ff:ff:f0,dl_type=0x0000 Rule: table=2 cookie=0 OpenFlow actions=learn(table=10,NXM_OF_VLAN_TCI[0..11],NXM_OF_ETH_DST[]=NXM_OF_ETH_SRC[],load:NXM_OF_IN_PORT[]->NXM_NX_REG0[0..15]),resubmit(,3) Resubmitted flow: unchanged Resubmitted regs: reg0=0x0 reg1=0x0 reg2=0x0 reg3=0x0 reg4=0x0 reg5=0x0 reg6=0x0 reg7=0x0 reg8=0x0 reg9=0x0 reg10=0x0 reg11=0x0 reg12=0x0 reg13=0x0 reg14=0x0 reg15=0x0 Resubmitted odp: drop Resubmitted megaflow: recirc_id=0,in_port=1,vlan_tci=0x0014/0x0fff,dl_src=f0:00:00:00:00:01,dl_dst=90:00:00:00:00:00/ff:ff:ff:ff:ff:f0,dl_type=0x0000 Rule: table=3 cookie=0 priority=50 OpenFlow actions=resubmit(,10),resubmit(,4) Resubmitted flow: unchanged Resubmitted regs: reg0=0x0 reg1=0x0 reg2=0x0 reg3=0x0 reg4=0x0 reg5=0x0 reg6=0x0 reg7=0x0 reg8=0x0 reg9=0x0 reg10=0x0 reg11=0x0 reg12=0x0 reg13=0x0 reg14=0x0 reg15=0x0 Resubmitted odp: drop Resubmitted megaflow: recirc_id=0,in_port=1,vlan_tci=0x0014/0x0fff,dl_src=f0:00:00:00:00:01,dl_dst=90:00:00:00:00:01,dl_type=0x0000 Rule: table=10 cookie=0 vlan_tci=0x0014/0x0fff,dl_dst=90:00:00:00:00:01 OpenFlow actions=load:0x2->NXM_NX_REG0[0..15] Resubmitted flow: reg0=0x2,in_port=1,dl_vlan=20,dl_vlan_pcp=0,dl_src=f0:00:00:00:00:01,dl_dst=90:00:00:00:00:01,dl_type=0x0000 Resubmitted regs: reg0=0x2 reg1=0x0 reg2=0x0 reg3=0x0 reg4=0x0 reg5=0x0 reg6=0x0 reg7=0x0 reg8=0x0 reg9=0x0 reg10=0x0 reg11=0x0 reg12=0x0 reg13=0x0 reg14=0x0 reg15=0x0 Resubmitted odp: drop Resubmitted megaflow: recirc_id=0,reg0=0/0xffff,in_port=1,vlan_tci=0x0014/0x0fff,dl_src=f0:00:00:00:00:01,dl_dst=90:00:00:00:00:01,dl_type=0x0000 Rule: table=254 cookie=0 priority=0,reg0=0x2 OpenFlow actions=drop Final flow: reg0=0x2,in_port=1,dl_vlan=20,dl_vlan_pcp=0,dl_src=f0:00:00:00:00:01,dl_dst=90:00:00:00:00:01,dl_type=0x0000 Megaflow: recirc_id=0,in_port=1,dl_vlan=20,dl_src=f0:00:00:00:00:01,dl_dst=90:00:00:00:00:01,dl_type=0x0000 Datapath actions: drop 

4:


4 0, , , 0 . , VLAN (802.1Q), .

— . p1:

 $ ovs-ofctl add-flow br0 "table=4 reg0=1 actions=1" 

VLAN :

 $ ovs-ofctl add-flows br0 - <<'EOF' table=4 reg0=2 actions=strip_vlan,2 table=4 reg0=3 actions=strip_vlan,3 table=4 reg0=4 actions=strip_vlan,4 EOF 

, MAC- . , VLAN- 802.1Q , :

 $ ovs-ofctl add-flows br0 - <<'EOF' table=4 reg0=0 priority=99 dl_vlan=20 actions=1,strip_vlan,2 table=4 reg0=0 priority=99 dl_vlan=30 actions=1,strip_vlan,3,4 table=4 reg0=0 priority=50 actions=1 EOF 

OpenFlow, , ., p1, p1, actions=1, , . , .

4


1


, p1 VLAN 30:

 $ ovs-appctl ofproto/trace br0 in_port=1,dl_dst=ff:ff:ff:ff:ff:ff,dl_vlan=30 

, 802.1Q p3 p4, VLAN:

 Datapath actions: pop_vlan,3,4 

, , p3:

 $ ovs-appctl ofproto/trace br0 in_port=3,dl_dst=ff:ff:ff:ff:ff:ff 

, p1 802.1Q p4 .

 Datapath actions: push_vlan(vid=30,pcp=0),1,pop_vlan,4 

Open vSwitch 4,push_vlan(vid=30,pcp=0),

, , VLAN p1.

 $ ovs-appctl ofproto/trace br0 in_port=1,dl_dst=ff:ff:ff:ff:ff:ff $ ovs-appctl ofproto/trace br0 in_port=1,dl_dst=ff:ff:ff:ff:ff:ff,dl_vlan=55 

:

 $ ovs-appctl ofproto/trace br0 in_port=1,dl_dst=ff:ff:ff:ff:ff:ff,dl_vlan=20 $ ovs-appctl ofproto/trace br0 in_port=2,dl_dst=ff:ff:ff:ff:ff:ff $ ovs-appctl ofproto/trace br0 in_port=4,dl_dst=ff:ff:ff:ff:ff:ff 

, :

 $ ovs-appctl ofproto/trace br0 in_port=4,dl_dst=01:00:00:00:00:00 $ ovs-appctl ofproto/trace br0 in_port=1,dl_dst=90:12:34:56:78:90,dl_vlan=20 $ ovs-appctl ofproto/trace br0 in_port=1,dl_dst=90:12:34:56:78:90,dl_vlan=30 

2: MAC-


, 3. MAC- p1 VLAN 30

 $ ovs-appctl ofproto/trace br0 in_port=1,dl_vlan=30,dl_src=10:00:00:00:00:01,dl_dst=20:00:00:00:00:01 -generate 

, , p3 p4, VLAN 30

 Datapath actions: pop_vlan,3,4 

MAC- p4

 $ ovs-appctl ofproto/trace br0 in_port=4,dl_src=20:00:00:00:00:01,dl_dst=10:00:00:00:00:01 -generate 

, — p1,

 Datapath actions: push_vlan(vid=30,pcp=0),1 

:

 $ ovs-appctl ofproto/trace br0 in_port=1,dl_vlan=30,dl_src=10:00:00:00:00:01,dl_dst=20:00:00:00:00:01 -generate 

, , — p4.

 Datapath actions: pop_vlan,4 

.

Source: https://habr.com/ru/post/325560/


All Articles