"dev" <dev-boun...@openvswitch.org> wrote on 06/25/2016 08:38:09 PM:
> From: John McDowall <jmcdow...@paloaltonetworks.com> > To: "dev@openvswitch.org" <dev@openvswitch.org> > Date: 06/25/2016 08:38 PM > Subject: Re: [ovs-dev] SFC summary? > Sent by: "dev" <dev-boun...@openvswitch.org> > > Ryan, > > Thanks for putting together the summary - I have a simple VNF case > working with a BiW VNF - very minimal testing. I have added the > logic to support multiple port-pairs but have not tested yet. I have > included a dump of the flows. The code is posted to https:// > github.com/doonhammer/ovs there is conflict with ovn-northd.c that I > need to look at but apart from that it is sync'ed with main. > > I like the idea of using the ACL table/feature for the flow- > classifier and I think the networking-sfc team does too. I am just > not quite sure how to implement. I create a new table "ls_in_chain" > there I create four rule sets for each port-chain, 2 if the flow is > treated as uni-directional. The lowest priority rule just steers the > traffic into the port chain, using the flow-calssifer rules, the > highest priority rule steers traffic through the port chain. So the > first rule would live in the ACL table in your model and the action > would send it to the start of the port-chain rule - somehow - not > clear how to do that. > > I am struggling to understand how this breaks the pipeline model - > just my lack of understanding. So any help/suggestions would be appreciated. > > The other big items IMHO are: > Load-balancing within port-pairs, in port-pair-groups > L2/L3 VNF Support > > As always suggestions/guidence is welcome. > > Regards > > John > > Snapshot of ovn-sbctl dump-flows: The reason I was concerned about breaking the pipeline model can be summed up in that I misunderstood the "output" statements in table 6 - I got the mistaken impression that the packets were being punted out to OF ports (skipping the egress pipeline and so I was trying to figure out how having VNFs on different chassis was going to work. The good news is that looking at the below, I see I was operating under a misconception. My apologies. Now, having said the above, I do see some things that I want to address: 1. I think we want to break the SFC processing into two table on the ingress side (and I'll explain in more detail below). 2. I see some things done in places that I don't expect 3. There appears to be some pieces of the current pipeline missing. 4. The logical flow rules below are still single network and therefore single tenant. I'd like to see what a multi-tenant with a shared NFV would look like. So I'm going to walk through and put in what I am thinking of and hopefully that will explain how I propose to handle the ACLs, the selection of PPs from a PPG, and handle a multistage chain. > datapath: 6d684845-2a66-43e6-913e-f559ee66ade7 Pipeline: ingress > table=0(ls_in_port_sec_l2), priority= 100, match=(eth.src[40]), > action=(drop;) > table=0(ls_in_port_sec_l2), priority= 100, match=(vlan.present), > action=(drop;) For the next four, typically the networking-ovn mechanism driver creates a logical port in the NB DB that corresponds to the neutron port, so I'd expect to see four logical ports in the NB DB with external-ids set to things like: {"neutron:port_name"="sw1-lport1"} and then I'd expect to see the name of the nb logical port (which is typically an UUID) as the inport below. I also set the PPG of the next port pair group, to avoid needing an extra table later on. Now, for L2 VNFs, I'd expect additional information about vlans and MAC addresses in rules that are higher than priority 100. For L3 VNFs, I'd also expect to see rules about MAC addresses. This is also where I struggle to make multi-tenancy work as these rules identify the inport with the logical datapath. At this point, I've not worked out a way to make multi-tenancy work unless there is metadata passed to and from the VNF to indentify the correct logical datapath to use and in that case, these rules will need to add that metadata to the match criteria. If you have a counter-example, I'd be happy to see it. table=0(ls_in_port_sec_l2), priority=50, match=(inport == "<PP from first PPG>"), action=(ppg=<UUID of Second PPG in PC>; next;) ... > table=0(ls_in_port_sec_l2), priority= 50, match=(inport == "sw1- > lportf1"), action=(next;) > table=0(ls_in_port_sec_l2), priority= 50, match=(inport == "sw1- > lportf2"), action=(next;) > table=0(ls_in_port_sec_l2), priority= 50, match=(inport == "sw1- > lport1"), action=(next;) > table=0(ls_in_port_sec_l2), priority= 50, match=(inport == "sw1- > lport2"), action=(next;) > table=0(ls_in_port_sec_l2), priority= 50, match=(inport == "sw1- > lportf1"), action=(next;) > table=0(ls_in_port_sec_l2), priority= 50, match=(inport == "sw1- > lportf2"), action=(next;) For L3 VNFs, I'd expect some entries in table 1 about the IP address of the VNF - things like priority=90, match=(inport == \"<inport>\" && eth.src == <VNF MAC> && ip4.src == {<VNF IPaddr>}), action=(next;) priority=80, match=(inport == \"<inport>\" && eth.src == <VNF MAC> && ip4), action=(drop;) > table=1(ls_in_port_sec_ip), priority= 0, match=(1), action=(next;) I also would expect to see some arp related items in table 2 for L2 and L3 VNFs like: priority=90, match=(inport == \"<inport>\" && eth.src == <VNF MAC> && arp.sha == <VNF_MAC> && (arp.spa == {<VNF IPaddr>})), action=(next;) priority=80, match=(inport == \"<inport>\" && (arp || nd)), action=(drop;) > table=2(ls_in_port_sec_nd), priority= 0, match=(1), action=(next;) For table 3, now that conntrack is part of the ACL processing, I would expect to see something like the following: priority=100, match=ip, action=(ct_next;) > table=3( ls_in_pre_acl), priority= 0, match=(1), action=(next;) Table 4 is where your ACL match comes in for traffic entering the first port of the port chain, and what I set here is the port_pair_group, because I want to put load balancing in the SFC table below. I'm also going to change my idea, because looking at this some more, I can solve my metadata concern if I move the PPG/PP selection logic to the ingress pipeline. Now, I'd also expect to see a bunch of conntrack rules that I'm not cover, as I want to concentrate on the ones specific to SFC (in this example, I'm assuming an ACL based on a classifier for HTTP, and the details might need to be corrected) priority=2002, match=(ct.new && (tcp && dst.port=80)), action=(ppg=<UUID of First PPG in PC>; ct_commit; next;) > table=4( ls_in_acl), priority= 0, match=(1), action=(next;) I'm good with table 5 entries > table=5( ls_in_arp_rsp), priority= 50, match=(arp.tpa == 172. > 16.33.2 && arp.op == 1), action=(eth.dst = eth.src; eth.src = 52:54: > 00:bd:04:28; arp.op = 2; /* ARP reply */ arp.tha = arp.sha; arp.sha > = 52:54:00:bd:04:28; arp.tpa = arp.spa; arp.spa = 172.16.33.2; > outport = inport; inport = ""; /* Allow sending out inport. */ output;) > table=5( ls_in_arp_rsp), priority= 50, match=(arp.tpa == 172. > 16.33.3 && arp.op == 1), action=(eth.dst = eth.src; eth.src = 52:54: > 00:20:47:62; arp.op = 2; /* ARP reply */ arp.tha = arp.sha; arp.sha > = 52:54:00:20:47:62; arp.tpa = arp.spa; arp.spa = 172.16.33.3; > outport = inport; inport = ""; /* Allow sending out inport. */ output;) > table=5( ls_in_arp_rsp), priority= 0, match=(1), action=(next;) Table 6 (ls_sfc stage) is where I select the output port, either via a select group for load balancing or via a direct set if the PPG has only a single PP in it. table=6( ls_sfc), priority=150, match=(ppg=<UUID of First PPG in PC>), action=(group_id=1,type==select, bucket="outport=\"<inport of first PP in PPG>\", output, bucket="outport=\"<inport of second PP in PPG>\", output; ... [as many buckets as there are PPs in the first PPG]) table=6( ls_sfc), priority=150, match=(ppg=<UUID of Second PPG in PC>), action=(group_id=2,type==select, bucket="outport=\"<inport of first PP in PPG>\", output, bucket="outport=\"<inport of second PP in PPG>\", output; ... [as many buckets as there are PPs in the second PPG]) ... as many entries as there are PPGs table=6( ls_sfc) priority=150, match=(ppg=<UUID of Third PPG in PC>), action-(outport="<inport of PP in Third PPG>", output;) table=6( ls_sfc) priority=1, match=(1), action=(next;) > table=6( ls_in_chain), priority= 150, match=(ip4.dst == 172. > 16.33.3 && inport == "sw1-lportf1"), action=(outport = "sw1-lport1"; output;) > table=6( ls_in_chain), priority= 150, match=(ip4.src == 172. > 16.33.3 && inport == "sw1-lport1"), action=(outport = "sw1-lportf1"; output;) > table=6( ls_in_chain), priority= 100, match=(inport == "sw1- > lportf2" && ip4.dst == 172.16.33.2), action=(outport = "sw1-lport2"; output;) > table=6( ls_in_chain), priority= 100, match=(inport == "sw1- > lportf2" && ip4.dst == 172.16.33.3), action=(outport = "sw1-lport1"; output;) > table=6( ls_in_chain), priority= 100, match=(ip4.dst == 172. > 16.33.3), action=(outport = "sw1-lportf2"; output;) > table=6( ls_in_chain), priority= 0, match=(1), action=(next;) I think the below is ok. > table=7( ls_in_l2_lkup), priority= 100, match=(eth.mcast), > action=(outport = "_MC_flood"; output;) > table=7( ls_in_l2_lkup), priority= 50, match=(eth.dst == 52: > 54:00:20:47:62), action=(outport = "sw1-lport1"; output;) > table=7( ls_in_l2_lkup), priority= 50, match=(eth.dst == 52: > 54:00:a8:01:fa), action=(outport = "sw1-lportf2"; output;) > table=7( ls_in_l2_lkup), priority= 50, match=(eth.dst == 52: > 54:00:af:74:f5), action=(outport = "sw1-lportf1"; output;) > table=7( ls_in_l2_lkup), priority= 50, match=(eth.dst == 52: > 54:00:bd:04:28), action=(outport = "sw1-lport2"; output;) > Datapath: 6d684845-2a66-43e6-913e-f559ee66ade7 Pipeline: egress Does that help or does it make things "clear as mud?" Ryan _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev