[P4-dev] Problem with OpenflowEnabledP4Switch

Antonin Bas antonin at barefootnetworks.com
Thu Dec 15 11:55:14 EST 2016


Yes that's a good catch.
You need a different veth for each switch's CPU port. Therefore you should:
- create 2 additional veth pairs for the 2 additional switches: for example
veth350-veth351 & veth450-veth451
- update main.c so that it takes the cpu veth as a command line parameter,
and use the appropriate one for each switch (veth250, veth350, veth450).
- update p4ofagent to use the appropriate veth for each switch. Right now
it seems that this is hard-coded to veth251 (
https://github.com/p4lang/p4ofagent/blob/master/src/cpu_packet.c#L72). My
recommendation would be to update p4ofagent_init (
https://github.com/p4lang/p4ofagent/blob/d620577b53f45b8176bf518bf581480d9022aff1/src/p4ofagent.c#L123)
to take the veth as an additional parameter (just like it takes the
controller ip as a parameter today). You can then pass the appropriate
value (veth251, veth351, veth451) from main.c:
https://github.com/p4lang/p4factory/blob/master/targets/l2_switch/main.c#L441.
If you do that change to p4ofagent, feel free to open a pull request so
that everyone can benefit.

Thanks,

Antonin

On Thu, Dec 15, 2016 at 8:10 AM, Tanja Ulmen <tanja.ulmen at rwth-aachen.de>
wrote:

> Hi,
>
> I found out that after sending the packet from sw1 to the controller, the
> packet is received by sw2 and sw3 but the packet is not handled, because
> there are table entries missing in these switches (because I thought this
> packet would not appear in these switches).
>
> Is it possible that the error occurs because all switches are connected to
> the same veth (250) in the main.c?:
>
> #ifdef ENABLE_PLUGIN_OPENFLOW
>     p4ofagent_init (of_ipv6, of_controller_str);
>     char pcap_filename_cpu[1024];
>     pcap_filename_cpu[0] = 0;
>     if (dump_pcap) {
>         snprintf(pcap_filename_cpu, 1024,
>                  "p4ns.%s-port%.2d.pcap", datapath_name, 64);
>     }
>     CHECK(bmi_port_interface_add(port_mgr, "veth250", 64,
> pcap_filename_cpu));
> #endif /* ENABLE_PLUGIN_OPENFLOW */
>
> I saw this right now. The whole main.c is more or less the same as in
> "https://github.com/p4lang/p4factory/blob/master/targets/l2_switch/main.c"
> <https://github.com/p4lang/p4factory/blob/master/targets/l2_switch/main.c>.
> Thus there was only one switch needed.
>
> Regards,
> Tanja
>
>
>
> Am 15.12.2016 um 09:57 schrieb Tanja Ulmen:
>
> Hi Antonin,
>
> yes I am still using the bmv1.
>
> In fact I didn't change the OpenflowEnabledP4Switch class. So the
> controllers parameter is still ignored and the command line parameter for
> the controller IP is used.
>
> I thought the P4 openflow agent instance is automatically starting with
> every switch instance that I start in mininet. So how do I explicitly start
> one with each switch?
>
> This is a part of the sw1 log:
>
> PD server address is 127.0.0.1:22223
> No listener specified, switch will run in standalone mode
> ##############################################################
>
> P4 Program:  control_target
>
> Starting RPC server on port 22223
> 12-15 09:01:28.236455 [ofconnectionmanager] Controller add: 127.0.0.1:6653
> (remote, v4)
> switch is adding port sw1-eth1 as 1
> switch is adding port sw1-eth2 as 2
> 12-15 09:01:28.284834 [ofconnectionmanager] Connected to controller
> 127.0.0.1:6653
> ofpat_group_egress: setting default action
> Adding interface sw1-eth1 (port 1)
> Adding interface sw1-eth2 (port 2)
> PktGen:Port[1] DOWN:HANDLING
> PktGen:Port[2] DOWN:HANDLING
> PktGen:Port[1] DOWN:NOT HANDLING
> PktGen:Port[2] DOWN:NOT HANDLING
> ...
> [Tables are added]
> ...
> Packet in on port 1 length 46; first bytes:
> 00000010 31010000 00104401 08004500
> new packet, len : 46, ingress : 1
> rmt proc returns 0
> ingress_pipeline: packet dequeued
> parsing start
> parsing parse_ethernet
> parsing parse_ipv4
> parsing parse_udp
> parsing parse_payload
> payload length: 0
> all checksums are correct
> Applying table ipv4_dst
> Lookup key for ipv4_dst:
>     ipv4_dstAddr: 0x0a00150a,
> table hit
>
> **********
> entry at index 6:
>     key:
>         ipv4_dstAddr: 0x0a00150a (10 0 21 10),
>     action:
>         set_nhop
>     action data:
>         nhop_ipv4: 0x0a00150a (10 0 21 10),    port: 0x00000003 (0 0 0
> 3),
> **********
>
> action set_nhop
> action data:
>     nhop_ipv4: 0x0a00150a (10 0 21 10),    port: 0x00000003 (0 0 0 3),
> executing next table for action
> Applying table forward
> Lookup key for forward:
>     routing_metadata_nhop_ipv4: 0x0a00150a,
> table hit
>
> **********
> entry at index 2:
>     key:
>         routing_metadata_nhop_ipv4: 0x0a00150a (10 0 21 10),
>     action:
>         set_dmac
>     action data:
>         dmac: 0x000000102110,
> **********
>
> action set_dmac
> action data:
>     dmac: 0x000000102110,
> executing next table for action
> Applying table read_ether_dst
> Lookup key for read_ether_dst:
>     ethernet_dstAddr: 0x000000102110, ipv4_dstAddr: 0x0a00150a,
> table hit
>
> **********
> entry at index 6:
>     key:
>         ethernet_dstAddr: 0x000000102110,    ipv4_dstAddr: 0x0a00150a (10
> 0 21 10),
>     action:
>         openflow_miss
>     action data:
>         reason: 0x00000000 (0 0 0 0),    table_id: 0x00000000 (0 0 0
> 0),
> **********
>
> action openflow_miss
> action data:
>     reason: 0x00000000 (0 0 0 0),    table_id: 0x00000000 (0 0 0 0),
> executing next table for action
> total length for outgoing pkt: 64
> deparsing ethernet
> deparsing fabric_header
> deparsing fabric_header_cpu
> deparsing fabric_payload_header
> deparsing ipv4
> deparsing udp
> deparsing paylo
> total length for outgoing meta: 44
> copying metadata
> deparsing standard_metadata
> deparsing openflow_metadata
> deparsing intrinsic_metadata
> deparsing routing_metadata
> queuing system: packet dequeued
> egress port set to 64
> instance type set to 0
> egress_pipeline: packet dequeued
> parsing start
> parsing parse_ethernet
> parsing parse_ipv4
> parsing parse_udp
> parsing parse_payload
> payload length: 18
> extracting metadata
> extracting all metadata for 0x7fd158000980
> Applying table send_frame
> Lookup key for send_frame:
>     standard_metadata_egress_port: 0x00000040,
> table miss, applying default action
> no default action, doing nothing
> total length for outgoing pkt: 64
> deparsing ethernet
> deparsing ipv4
> deparsing udp
> deparsing paylo
> outgoing thread: packet dequeued
> outgoing thread: sending pkt: Size[64]: Port[64]
>
> This is how the respective packet is handled in the sw1. In sw2 this
> packet (coming from sens1) is only forwarded to sw1 and sw3 does not get a
> packet at all (that is correct).
>
> The table read_ether_dst is the table that is exposed to openflow via the
> openflow_mapping.
>
> openflow_tables = {
>     "read_ether_dst": OFTable(
>         match_fields = {
>             "eth_dstAddr"    : OFMatchField(field="OFPXMT_OFB_ETH_DST"),
>             "ipv4_dstAddr"    : OFMatchField(field="OFPXMT_OFB_IPV4_DST")
>         },
>
>         id = 0
>     )
> }
>
> This is the table entry of sw1 to send all packets with the destination
> 10.0.21.10 to the controller.
>
> add_entry read_ether_dst 00:00:00:10:21:10 10.0.21.10 openflow_miss 0 0
>
> This entry is not available in sw2 and sw3.
>
> Thanks,
> Tanja
>
>
>
>
> Am 14.12.2016 um 22:54 schrieb Antonin Bas:
>
> Hi Tanja,
>
> I am not sure this is enough information for us to help you. Maybe if you
> could share the relevant parts of the logs for each switch it would help.
> I notice that in your Mininet script, you call start([c0]) for each
> switch. When I look at the start method for the OpenflowEnabledP4Switch in
> p4lang/p4factory (https://github.com/p4lang/p4factory/blob/master/mininet/
> openflow_l2.py#L140), I see that the "controllers" parameter is
> completely ignored and that instead we rely on a command line parameter for
> the controller IP. I suppose you updated OpenflowEnabledP4Switch to not
> ignore "controllers"?
> You should also be starting one P4 openflow agent instance per switch (
> https://github.com/p4lang/p4ofagent). As far as I know, there is no super
> easy way to do this with bmv2 (except for switch.p4), so you are probably
> using bmv1?
>
> Thanks,
>
> Antonin
>
> On Wed, Dec 14, 2016 at 5:52 AM, Tanja Ulmen <tanja.ulmen at rwth-aachen.de>
> wrote:
>
>> Hi,
>>
>> I have a mininet topology with three OpenflowEnabledP4Switches that is
>> build like this:
>>
>> def myNetwork():
>>     behavioral_model = os.path.join(sys.path[0],
>> '../targets/control_target/behavioral-model')
>>     net = Mininet( topo= None, host= P4Host, build=False, switch =
>> OpenflowEnabledP4Switch)
>>
>>     info( '*** Adding controller\n' )
>>     c0=net.addController(name='c0', controller=RemoteController,
>> ip='127.0.0.1', port=6653)
>>
>>     info( '*** Add switches\n')
>>     sw1 = net.addSwitch('sw1', sw_path = behavioral_model, dpid="01",
>> thrift_port = 22223, pcap_dump = True)
>>     sw2 = net.addSwitch('sw2', sw_path = behavioral_model, dpid="02",
>> thrift_port = 22224, pcap_dump = True)
>>     sw3 = net.addSwitch('sw3', sw_path = behavioral_model, dpid="03",
>> thrift_port = 22225, pcap_dump = True)
>>
>>     info( '*** Add hosts\n')
>>     sens1 = net.addHost('sens1', cls=P4Host, ip='10.0.1.10/24',
>> mac='00:00:00:10:01:10')
>>
>>     info( '*** Add links\n')
>>     net.addLink(sens1, sw2)
>>     net.addLink(sw1, sw2)
>>     net.addLink(sw1, sw3)
>>
>>     info( '*** Starting network\n')
>>     net.build()
>>
>>     info( '*** Starting switches\n')
>>     net.get('sw1').start([c0])
>>     net.get('sw2').start([c0])
>>     net.get('sw3').start([c0])
>> ...
>>
>>
>> The class OpenflowEnabledP4Switch is similar to the one of the
>> openflow_l2.py in p4factory/mininet/. The switches are connected to a Ryu
>> controller. Sw2 and Sw3 have tables to forward the data to Sw1 and Sw1
>> sends the data to the Ryu controller with an openflow_miss. All data that
>> is sent from Sw1 to the controller is received by the controller, but my
>> problem is that it is received three times. By analyzing the packets with
>> wireshark, it seems that the controller receives one duplicate of this
>> message from every switch. In the log files of the switches only Sw1 is
>> sending the packet once to the controller.
>>
>> When I use the Ryu Topology Viewer only one switch is visible instead of
>> three. When I use the same topology but with normal switches (not P4) then
>> all three switches are visible. So maybe the three switches are not really
>> separated?
>>
>> Do you have any ideas why the other switches also send messages to the
>> controller without telling them to do so? I hope it's possible to
>> understand my problem.
>>
>> Best regards,
>> Tanja
>>
>>
>>
>> _______________________________________________
>> P4-dev mailing list
>> P4-dev at lists.p4.org
>> http://lists.p4.org/mailman/listinfo/p4-dev_lists.p4.org
>>
>
>
>
> --
> Antonin
>
>
>
>
> _______________________________________________
> P4-dev mailing listP4-dev at lists.p4.orghttp://lists.p4.org/mailman/listinfo/p4-dev_lists.p4.org
>
>
>


-- 
Antonin
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.p4.org/pipermail/p4-dev_lists.p4.org/attachments/20161215/70ee7d4f/attachment-0002.html>


More information about the P4-dev mailing list