Re: [ovs-dev] [PATCH RFC v2 3/3] ovn: add SLAAC support for IPv6
On Mon, Aug 1, 2016 at 7:16 PM, Zong Kai LI wrote: > This patch tries to implement Router Advertisement (RA) responder for SLAAC > on ovn-northd side. > > It tries to build lflows per each Logical Router Port, who have IPv6 > networks > and set their 'slaac' column to true. > > The lflows will look like: > match=(inport == "lrp-32a71e0b-8b19-4c52-8cde-058325e4df5d" && > ip6.dst == ff02::2 && nd_rs) > action=(nd_ra{slaac(fd80:a123:b345::/64,1450,fa:16:3e:62:f1:e6); > outport = inport; flags.loopback = 1; output;};) > while: > - nd_rs is a new symbol stands for >"icmp6.type == 133 && icmp6.code == 0 && ttl == 255" > - slaac is a new action which accepts ordered parameter list: > - one or more IPv6 prefixes: such as fd80:a123:b345::/64. > - MTU: logical switch MTU, such as 1450. > - MAC address: router port mac address, such as fa:16:3e:62:f1:e6. > - nd_ra is a new action which stands for RA responder, it will compose a > RA >packet per parameters in slaac, and eth.src and ip6.src from packet > being >processed. > This would be a router solicitation responder, since it responds to router solicitation messages by sending router advertisement messages. > > Logical_Router_Port.slaac column will only tell whether ovn should reply a > RA > packet for Router solicitation packet received from the lrp port. To > respond > a RA packet for other scenario will be a future work. > --- > ovn/northd/ovn-northd.c | 94 > ovn/ovn-nb.ovsschema| 6 ++- > ovn/ovn-nb.xml | 11 + > tests/ovn.at| 111 ++ > ++ > 4 files changed, 213 insertions(+), 9 deletions(-) > > diff --git a/ovn/northd/ovn-northd.c b/ovn/northd/ovn-northd.c > index d6c14cf..98db819 100644 > --- a/ovn/northd/ovn-northd.c > +++ b/ovn/northd/ovn-northd.c > @@ -126,9 +126,10 @@ enum ovn_stage { > PIPELINE_STAGE(ROUTER, IN, IP_INPUT,1, "lr_in_ip_input") \ > PIPELINE_STAGE(ROUTER, IN, UNSNAT, 2, "lr_in_unsnat") \ > PIPELINE_STAGE(ROUTER, IN, DNAT,3, "lr_in_dnat") \ > -PIPELINE_STAGE(ROUTER, IN, IP_ROUTING, 4, "lr_in_ip_routing") \ > -PIPELINE_STAGE(ROUTER, IN, ARP_RESOLVE, 5, "lr_in_arp_resolve") \ > -PIPELINE_STAGE(ROUTER, IN, ARP_REQUEST, 6, "lr_in_arp_request") \ > +PIPELINE_STAGE(ROUTER, IN, RA_RSP, 4, "lr_in_ra_rsp") \ Since this is responding to router solicitation messages, should this be RS_RSP? > +PIPELINE_STAGE(ROUTER, IN, IP_ROUTING, 5, "lr_in_ip_routing") \ > +PIPELINE_STAGE(ROUTER, IN, ARP_RESOLVE, 6, "lr_in_arp_resolve") \ > +PIPELINE_STAGE(ROUTER, IN, ARP_REQUEST, 7, "lr_in_arp_request") \ >\ > /* Logical router egress stages. */ \ > PIPELINE_STAGE(ROUTER, OUT, SNAT, 0, "lr_out_snat") \ > @@ -3409,7 +3443,51 @@ build_lrouter_flows(struct hmap *datapaths, struct > hmap *ports, >"ip", "flags.loopback = 1; ct_dnat;"); > } > > -/* Logical router ingress table 4: IP Routing. > +/* Logical router ingress table 5: RA responder, by default goto next. > Isn't this table 4 now? > + * (priority 0)*/ > +HMAP_FOR_EACH (od, key_node, datapaths) { > +if (!od->nbr) { > +continue; > +} > + > +ovn_lflow_add(lflows, od, S_ROUTER_IN_RA_RSP, 0, "1", "next;"); > +} > + > +/* Logical router ingress table 5: RA responder, reply for 'slaac' > enabled > + * router port. (priority 50)*/ > +HMAP_FOR_EACH (op, key_node, ports) { > +if (!op->nbrp || op->nbrp->peer > +|| !op->peer > +|| !op->nbrp->slaac > +|| !*op->nbrp->slaac) { > +continue; > +} > + > +ds_clear(&match); > +ds_put_format(&match, "inport == %s", op->json_key); > +ds_put_cstr(&match, " && ip6.dst == ff02::2 && nd_rs"); > +ds_clear(&actions); > +ds_put_format(&actions, "nd_ra{slaac("); > +size_t actions_len = actions.length; > +for (size_t i = 0; i != op->lrp_networks.n_ipv6_addrs; i++) { > +if (in6_is_lla(&op->lrp_networks.ipv6_addrs[i].network)) { > +continue; > +} > +ds_put_format(&actions, "%s/%u,", > + op->lrp_networks.ipv6_addrs[i].network_s, > + op->lrp_networks.ipv6_addrs[i].plen); > +} > +if (actions.length != actions_len) { > +ds_put_format(&actions, "%ld,", op->peer->od->nbs->mtu); > +ds_put_cstr(&actions, op->lrp_networks.ea_s); > +ds_put_cstr(&actions, "); outport = inport; flags.loopback = > 1;" > + " output;};"); > +ovn_lflow_add(lflows, op->od, S_ROUTER_IN_RA_RSP, 50, > +
Re: [ovs-dev] [PATCH RFC v2 2/3] ovn: add SLAAC support for IPv6
+ > +struct ofputil_packet_out po = { > +.packet = dp_packet_data(&packet), > +.packet_len = dp_packet_size(&packet), > +.buffer_id = UINT32_MAX, > +.in_port = OFPP_CONTROLLER, > +.ofpacts = ofpacts.data, > +.ofpacts_len = ofpacts.size, > +}; > + > +queue_msg(ofputil_encode_packet_out(&po, proto)); > + > +exit: > +dp_packet_uninit(&packet); > +ofpbuf_uninit(&ofpacts); > +} > diff --git a/ovn/ovn-sb.xml b/ovn/ovn-sb.xml > index 13c9526..66a9009 100644 > --- a/ovn/ovn-sb.xml > +++ b/ovn/ovn-sb.xml > @@ -1151,8 +1151,38 @@ > > > > -get_nd(P, A); > + > + nd_ra { slaac(...); action; > ... }; > + > + > + > + > +Generate an IPv6 Router Advertisement (RA) packet per inner > action > +'slaac' ordered parameters, and eth.src and ip6.src from > Router > +Solicitation (RS) packet being processed. > +Parameters: One or more IPv6 prefixes, 16-bit MUT, > 48-bit > MTU? > +mac address. > +Then executes each nested action on the RA packet. > +Actions following the ra action, if any, apply to > the > + original, unmodified packet. > +The composed RA packet will use RS packet eth.src as eth.dst, > use > +RS packet ip6.src as ip6.dst, and use 'slaac' action > parameter mac > +address and its lla as eth.src and ip6.src. > + > + > + > +The RA packet has the same VLAN header, if any, as the IPv6 > packet > +it replaces. > + > > + > +Prerequisite: nd_rs > + > + > + > +get_arp(P, A); > + > +get_nd(P, A); > > > Parameters: logical port string field P, > 128-bit > > Is there a reason for specifying the prefixes as the first arguments to slaac()? Usually variable number arguments are passed last after any fixed arguments, I would recommend `slacc(sll, mtu, prefix1, ...)` instead. Other packet in handlers like pinctrl_handle_arp() only accept the flow_metadata rather than the entire packet, any reason for this change since only the metadata is used? Finally tests/test-ovn.c and tests/ovn.at didn't apply cleanly. Thanks, Dustin Lundquist ___ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev
Re: [ovs-dev] [PATCH RFC v2 1/3] ovn: add SLAAC support for IPv6
On Mon, Aug 1, 2016 at 7:16 PM, Zong Kai LI wrote: > This patch introduces methods to compose a Router Advertisement (RA) > packet, > introduces flags for RA, renames ovs_nd_opt to ovs_nd_lla_opt to specify > it's > Source/Target Link-layer Address option. > > Signed-off-by: Zong Kai LI > --- > lib/flow.c| 26 - > lib/odp-execute.c | 20 +++ > lib/packets.c | 168 ++ > +++- > lib/packets.h | 86 > 4 files changed, 239 insertions(+), 61 deletions(-) > Reviewed packet structures against specification in RFC4861. Acked-by: Dustin Lundquist ___ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev
Re: [ovs-dev] [PATCH] ovs : Implementation to add meter in ovs flows
On 7/15/16 12:32 AM, deepanshu.saxen...@gmail.com wrote: > From: Deepanshu Saxena > > This commit implements ovs meters in kernel space using the traffic > control (tc) module of Linux kernel. TC is used to configure Traffic > Control features like Policing, Shaping etc. Ovs meters are analogous to > traffic control policing feature. The details from the meter command are > fetched and mapped to the corresponding fields of tc qdisc,class,filter > commands. Great idea. Doesn't TC the TC system only perform actions when a frame is egresses from an interface. Without additional TC hooks within the kernel datapath, this metering will not affect traffic send of vswitchd via upcalls. I would like to see a more universal metering solution which works with all traffic passing through OVS. > diff --git a/ofproto/meter_tc.c b/ofproto/meter_tc.c > new file mode 100644 > index 000..fc7fa0b > --- /dev/null > +++ b/ofproto/meter_tc.c > @@ -0,0 +1,74 @@ > +#include > +#include "meter_tc.h" > + > +VLOG_DEFINE_THIS_MODULE(meter_tc); > + > +enum ofperr flow_mod_to_tc(struct ofproto *ofproto, > + struct ofputil_flow_mod ofm) { > +FILE *fp; > +ovs_be32 nw_src,nw_dst; > +struct ofpact *a; > +struct ofpact_meter *m_act; > +struct ofport *ofport; > +struct meter *meter; > +uint32_t id,rate,rate_in_bytesps,burst_size,default_id; > +char buffer[1024]; > +ofp_port_t port=0; > +default_id=65535; > +id=0; > +struct ds nw_src_string = DS_EMPTY_INITIALIZER; > +struct ds nw_dst_string = DS_EMPTY_INITIALIZER; > +nw_src = ofm.match.flow.nw_src; > +nw_dst = ofm.match.flow.nw_dst; > +ds_put_format(&nw_src_string, IP_FMT, IP_ARGS(nw_src)); > +ds_put_format(&nw_dst_string, IP_FMT, IP_ARGS(nw_dst)); > +VLOG_INFO("Source IP : %s , Destination IP : %s",nw_src_string.string, > + nw_dst_string.string); > +OFPACT_FOR_EACH_FLATTENED (a, ofm.ofpacts, ofm.ofpacts_len) { > +if (a->type == OFPACT_METER) { > +m_act=ofpact_get_METER(a); > +id=m_act->meter_id; > +} > +if(a->type == OFPACT_OUTPUT) { > +port=ofpact_get_OUTPUT(a)->port; > +} > +} > +VLOG_INFO("Output Port Number : %d",port); > +ofport=ofproto_get_port(ofproto,port); > +if(ofport==NULL) { > +VLOG_INFO("The port numbers defined in the flow donot correspond to " > + "any datapath port. try using ovs-ofctl show to " > + "get the list of ports. Add ports to the bridge first"); > +return OFPERR_OFPBRC_BAD_PORT; > +} > +VLOG_INFO("Output Port Name : %s",ofport->pp.name); > +VLOG_INFO("Meter id : %d",id); > +meter = ofproto->meters[id]; > +rate=meter->bands->rate; > +rate_in_bytesps=(uint32_t)((float)(meter->bands->rate/8)*1000); > +burst_size=meter->bands->burst_size; > +VLOG_INFO("Rate in kbitsps : %d, burst size in kbits %d",rate, > + burst_size); > +snprintf(buffer,sizeof(buffer),"tc qdisc add dev %s root " > + "handle 1: htb default %x",ofport->pp.name,default_id); > +fp=popen(buffer,"r"); > +snprintf(buffer,sizeof(buffer),"tc class add dev %s parent 1:0 " > + "classid 1:%x htb rate 20kbps ceil 100kbps prio 2", > + ofport->pp.name,default_id); > +fp = popen(buffer,"r"); > +pclose(fp); We should check the exit code to ensure the tc command completed successfully. > +snprintf(buffer,sizeof(buffer),"tc class add dev %s parent 1:0 classid " > + "1:%x htb rate %dkbit ceil %dkbit prio 1 mtu %d000 ", > + ofport->pp.name,id,rate,rate,burst_size); > +fp = popen(buffer,"r"); > +pclose(fp); Ditto. > +snprintf(buffer,sizeof(buffer),"tc filter add dev %s protocol ip parent > " > + "1: prio 1 u32 match ip src %s match ip dst %s flowid 1:%x " > + "police rate %dbps burst %d000 mpu 0 conform-exceed drop/ok", > + ofport->pp.name,nw_src_string.string,nw_dst_string.string, > + id,rate_in_bytesps,burst_size); > +fp = popen(buffer,"r"); > +VLOG_INFO("Meter attached successfully to the flow"); > +pclose(fp); > +return 0; > +} ___ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev
[ovs-dev] [ovs-dev, v2][PATCH] ovn-northd: Restrict use of unspecified source addresses
Restrict use of the unspecified source addresses (:: and 0.0.0.0) to traffic necessary to obtain an IP address. DHCP discovery messages for the IPv4 case, and ICMP6 types necessary for duplicate address detection for IPv6. This breaks the existing ovn -- portsecurity : 3 HVs, 1 LS, 3 lports/HV test since it tests sourcing IPv6 packets from the unspecified address with and invalid ICMPv6 type (0). Modified this test should be extended to verify ICMPv6 types for DAD are permitted, and other IPv6 traffic sourced from the unspecified address are dropped. Signed-off-by: Dustin Lundquist --- ovn/northd/ovn-northd.8.xml | 16 ovn/northd/ovn-northd.c | 38 ++ tests/ovn.at| 24 +++- 3 files changed, 73 insertions(+), 5 deletions(-) diff --git a/ovn/northd/ovn-northd.8.xml b/ovn/northd/ovn-northd.8.xml index 970c352..2665ed5 100644 --- a/ovn/northd/ovn-northd.8.xml +++ b/ovn/northd/ovn-northd.8.xml @@ -160,12 +160,28 @@ +Priority 90 flow to allow IPv4 DHCP discovery traffic if it has a +valid eth.src. This is necessary since DHCP discovery +messages are sent from the unspecified IPv4 address (0.0.0.0) since +the IPv4 address has not yet been assigned. + + + Priority 90 flow to allow IPv6 traffic if it has IPv6 addresses which match the inport, valid eth.src and valid ip6.src address(es). +Priority 90 flow to allow IPv6 DAD (Duplicate Address Detection) +traffic if it has a valid eth.src. This is is +necessary since DAD include requires joining an multicast group and +sending neighbor solicitations for the newly assigned address. Since +no address is yet assigned, these are sent from the unspecified +IPv6 address (::). + + + Priority 80 flow to drop IP (both IPv4 and IPv6) traffic which match the inport and valid eth.src. diff --git a/ovn/northd/ovn-northd.c b/ovn/northd/ovn-northd.c index 44e9430..ad1f381 100644 --- a/ovn/northd/ovn-northd.c +++ b/ovn/northd/ovn-northd.c @@ -1033,12 +1033,17 @@ build_port_security_ipv6_flow( ipv6_string_mapped(ip6_str, &lla); ds_put_format(match, "%s, ", ip6_str); -/* Allow ip6.src=:: and ip6.dst=ff00::/8 for ND packets */ -ds_put_cstr(match, pipeline == P_IN ? "::" : "ff00::/8"); +/* Allow ip6.dst=ff00::/8 for multicast packets */ +if (pipeline == P_OUT) { +ds_put_cstr(match, "ff00::/8, "); +} for(int i = 0; i < n_ipv6_addrs; i++) { ipv6_string_mapped(ip6_str, &ipv6_addrs[i].addr); -ds_put_format(match, ", %s", ip6_str); +ds_put_format(match, "%s, ", ip6_str); } +/* Replace ", " by "}". */ +ds_chomp(match, ' '); +ds_chomp(match, ','); ds_put_cstr(match, "}"); } @@ -1174,8 +1179,19 @@ build_port_security_ip(enum ovn_pipeline pipeline, struct ovn_port *op, if (ps.n_ipv4_addrs) { struct ds match = DS_EMPTY_INITIALIZER; if (pipeline == P_IN) { +/* Permit use of the unspecified address for DHCP discovery */ +struct ds dhcp_match = DS_EMPTY_INITIALIZER; +ds_put_format(&dhcp_match, "inport == %s" + " && eth.src == "ETH_ADDR_FMT + " && ip4.src == 0.0.0.0" + " && ip4.dst == 255.255.255.255" + " && udp.src == 68 && udp.dst == 67", op->json_key, + ETH_ADDR_ARGS(ps.ea)); +ovn_lflow_add(lflows, op->od, stage, 90, + ds_cstr(&dhcp_match), "next;"); +ds_destroy(&dhcp_match); ds_put_format(&match, "inport == %s && eth.src == "ETH_ADDR_FMT - " && ip4.src == {0.0.0.0, ", op->json_key, + " && ip4.src == {", op->json_key, ETH_ADDR_ARGS(ps.ea)); } else { ds_put_format(&match, "outport == %s && eth.dst == "ETH_ADDR_FMT @@ -1219,6 +1235,20 @@ build_port_security_ip(enum ovn_pipeline pipeline, struct ovn_port *op, if (ps.n_ipv6_addrs) { struct ds match = DS_EMPTY_INITIALIZER; +if (pipeline == P_IN) { +/* Permit use of unspecified address for duplicate address + * detection */ +struct ds dad_match = DS_EMP
[ovs-dev] [PATCH] Restrict use of unspecified source addresses
Restrict use of the unspecified source addresses (:: and 0.0.0.0) to traffic necessary to obtain an IP address. DHCP discovery messages for the IPv4 case, and ICMP6 types necessary for duplicate address detection for IPv6. This breaks the existing ovn -- portsecurity : 3 HVs, 1 LS, 3 lports/HV test since it tests sourcing IPv6 packets from the unspecified address with and invalid ICMPv6 type (0). Modified this test should be extended to verify ICMPv6 types for DAD are permitted, and other IPv6 traffic sourced from the unspecified address are dropped. --- ovn/northd/ovn-northd.c | 37 + tests/ovn.at| 22 +- 2 files changed, 54 insertions(+), 5 deletions(-) diff --git a/ovn/northd/ovn-northd.c b/ovn/northd/ovn-northd.c index 44e9430..f59faa2 100644 --- a/ovn/northd/ovn-northd.c +++ b/ovn/northd/ovn-northd.c @@ -1033,12 +1033,16 @@ build_port_security_ipv6_flow( ipv6_string_mapped(ip6_str, &lla); ds_put_format(match, "%s, ", ip6_str); -/* Allow ip6.src=:: and ip6.dst=ff00::/8 for ND packets */ -ds_put_cstr(match, pipeline == P_IN ? "::" : "ff00::/8"); +/* Allow ip6.dst=ff00::/8 for multicast packets */ +if (pipeline == P_OUT) +ds_put_cstr(match, "ff00::/8, "); for(int i = 0; i < n_ipv6_addrs; i++) { ipv6_string_mapped(ip6_str, &ipv6_addrs[i].addr); -ds_put_format(match, ", %s", ip6_str); +ds_put_format(match, "%s, ", ip6_str); } +/* Replace ", " by "}". */ +ds_chomp(match, ' '); +ds_chomp(match, ','); ds_put_cstr(match, "}"); } @@ -1174,8 +1178,19 @@ build_port_security_ip(enum ovn_pipeline pipeline, struct ovn_port *op, if (ps.n_ipv4_addrs) { struct ds match = DS_EMPTY_INITIALIZER; if (pipeline == P_IN) { +/* Permit use of the unspecified address for DHCP discovery */ +struct ds dhcp_match = DS_EMPTY_INITIALIZER; +ds_put_format(&dhcp_match, "inport == %s" + " && eth.src == "ETH_ADDR_FMT + " && ip4.src == 0.0.0.0" + " && ip4.dst == 255.255.255.255" + " && udp.src == 68 && udp.dst == 67", op->json_key, + ETH_ADDR_ARGS(ps.ea)); +ovn_lflow_add(lflows, op->od, stage, 90, + ds_cstr(&dhcp_match), "next;"); +ds_destroy(&dhcp_match); ds_put_format(&match, "inport == %s && eth.src == "ETH_ADDR_FMT - " && ip4.src == {0.0.0.0, ", op->json_key, + " && ip4.src == {", op->json_key, ETH_ADDR_ARGS(ps.ea)); } else { ds_put_format(&match, "outport == %s && eth.dst == "ETH_ADDR_FMT @@ -1219,6 +1234,20 @@ build_port_security_ip(enum ovn_pipeline pipeline, struct ovn_port *op, if (ps.n_ipv6_addrs) { struct ds match = DS_EMPTY_INITIALIZER; +if (pipeline == P_IN) { +/* Permit use of unspecified address for duplicate address + * detection */ +struct ds dad_match = DS_EMPTY_INITIALIZER; +ds_put_format(&dad_match, "inport == %s" + " && eth.src == "ETH_ADDR_FMT + " && ip6.src == ::" + " && ip6.dst == ff02::/16" + " && icmp6.type == {131, 135, 143}", op->json_key, + ETH_ADDR_ARGS(ps.ea)); +ovn_lflow_add(lflows, op->od, stage, 90, + ds_cstr(&dad_match), "next;"); +ds_destroy(&dad_match); +} ds_put_format(&match, "%s == %s && %s == "ETH_ADDR_FMT"", port_direction, op->json_key, pipeline == P_IN ? "eth.src" : "eth.dst", diff --git a/tests/ovn.at b/tests/ovn.at index cc5c468..011472c 100644 --- a/tests/ovn.at +++ b/tests/ovn.at @@ -1786,6 +1786,19 @@ test_ipv6() { done } +# ipv6 icmp packet +test_icmpv6() { +local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5 icmp_type=$6 +local packet=${dst_mac}${src_mac}86dd60083aff${src_ip}${dst_ip}${icmp_type}00 +shift; shift; shift; shift; shift; shift +hv=`vif_to_hv $inport` +as $hv ovs-appctl netdev-dummy/receive vif$inport $packet +#as $hv ovs-appctl ofproto/trace br-int in_port=$inport $packet +for outport; do +echo $packet | trim_zeros >> $outport.expected +done +} + ip_to_hex() { printf "%02x%02x%02x%02x" "$@" } @@ -1923,8 +1936,15 @@ for i in 1 2 3; do sip=fe80ea2aeafffe2800${i}3 test_ipv6 ${i}3 f${i}${i}3 f021 $sip $tip 21 +# Test ICMPv6 MLD reports (v1 and v2) and NS for DAD sip=
Re: [ovs-dev] [PATCH V1 1/1] Support for Flooding ARP Probes in Provider Network
On 4/8/16 10:00 AM, Gangadhar R Vegesana wrote: > HI Dustin, > > *Case 1)* External Gateway or External Host have IP and now VM is > assigned the same IP, > VM should decline or not use that IP (ie. Send DCHP Decline in case of > DHCP). The ARP probe that is sent by VM should reach the External > Gateway/Host to get response back. I added that new entry to flood that > ARP Probe. Without this entry, the OVN ARP res-ponder, responds back to > the VM and there is no way VM knowing that there exists some conflict. > Once the conflict is known, either CMS or DHCP Server have to fix this, > by assigning a new IP to the VM. > > *Case 2)* VM have IP and External Gateway or External Host is assigned > the same IP : > This issue should be resolved by Gateway or External Host Admin, as > he/she is the one who is configuring the conflicting IP in the second place. > > I agree with you, that this is job of CMS to not allocate this IP > address, but this ARP probe is one such way to know that there exists > some conflict. From my understanding, i assume that OVN ARP responder > table won't have External Gateway ARP entry in its table. If we start > learning provider network (localnet) ARP entries, they can be huge > number (i assume) and OVN won't have control on these external entries. > Please let me know your thoughts. Let me try to break this into two separate topics: cost/benefit analysis of permitting ARP probes and learning provider network addresses for ARP responder. Regarding permitting ARP probes, my initial thought is that there is a higher than normal cost to broadcast/multicast traffic in OVN since traffic must be replicated and sent via unicast through each tunnel. I know there is work in progress to change this, but as I understand it this is the reasoning behind filtering ARP probes. But this is not the case in provider networks, since there is not a increased normal cost in handling broadcast and multicast traffic; this traffic is simply forwarded to the provider network interface and traffic is this replicated on the upstream network device. So performance impact of permitting ARP probes is not significant. Unfortunately the benefit of permitting ARP probes is rather low. Since ports in OVN are programmed with their L2 and L3 addresses and flows are created before an VM is connected to this port _the damage is already done_ (atleast to all the hosts connected via OVN) before the VM could perform an ARP probe to find out if its IP is in use. For this work as desired OVN would need to perform the ARP probe before creating the flows for the new IP address ARP responder. This would add a significant delay in flow creation. A learning ARP responder provides another option for managing duplicate IP addresses. While the number of address may be large, in conventional deployments it is only a small number of addresses with less churn than other OVN ports. With a mechanism to receive ARP responses from provider network devices and add them to the northbound database, OVN could return an error when a CMS attempts to provision a port with a duplicate address. This would not work well, if for example a user deployed a provider network connected to a campus wireless network or similar large L2 network with a high degree of address churn, but I don't think this is a use case we should design for. -Dustin ___ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev
Re: [ovs-dev] [PATCH V1 1/1] Support for Flooding ARP Probes in Provider Network
On 4/7/16 11:43 AM, Gangadhar Vegesana wrote: > Clients that supports RFC 5227, probes the the newly received IP address > from DHCP server. These probes should be received by all the VM's on > the provider network(localnet). I added any entry in ARP response table > to do that broadcast with higher priority value than that of ARP response > entries. The ARP probe packets with src=0.0.0.0 should not be dropped. > As of now there is check in ARP spoofing table to drop these packets. > Added another check to allow these packets I don't see the value in enabling RFC 5227 on an OVN provider networks. The most common use of a provider network is to connect with an external gateway, and this this case the gateway would not want to yield that IP. The CMS using OVN should not allocate addresses in conflict a provider network gateway. While without these ARP probes the provider network gateway would not learn of the potential address conflicts, allowing an address conflict. The ARP responder within OVN would override the provider network gateway ARP entry with the one for the new conflicting port configured by the CMS. In either case it is an error, and enabling ARP probes does not solve the problem of a CMS which erroneously configures a port with a conflicting IP to a provider network gateway. Perhaps it would be better if OVN could learn provider network gateway ARP entries and include them in its ARP responder? -Dustin Lundquist ___ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev
[ovs-dev] upcall fairness
I have some concerns about the fairness of upcalls and flow cache evictions in the kernel dataplane. My motivation for investigating this is based on my experience operating a hardware vendor's solution which use a similar method: caching routing decisions as flows after the first packet was punted to software. Operating a network using such hardware, we found a single host could generate traffic which would force cache evictions adversely effecting other hosts' traffic. As OVS uses a similar approach, I wanted to test how well it handles a malicious or compromised host connected to one of its ports. To test this I used Devstack with networking-ovn and created three neutron probe namespaces on a single network. Within one of the namespaces I used the Linux pktgen[1] kernel module to generate a large number of MAC flows[2]. I found ovs-vswitchd exhibited high CPU utilization, evidence of datapath flow evictions in latencies of a single ping test: > ubuntu@devstack-ovn:~$ sudo ip netns exec > qprobe-1739b61e-4085-43b5-bd4e-05051a11d996 ping -c 10 10.0.0.2 > PING 10.0.0.2 (10.0.0.2) 56(84) bytes of data. > > 64 bytes from 10.0.0.2: icmp_seq=1 ttl=64 time=11.1 ms > > 64 bytes from 10.0.0.2: icmp_seq=2 ttl=64 time=0.091 ms > > 64 bytes from 10.0.0.2: icmp_seq=3 ttl=64 time=2.28 ms > > 64 bytes from 10.0.0.2: icmp_seq=4 ttl=64 time=2.69 ms > > 64 bytes from 10.0.0.2: icmp_seq=5 ttl=64 time=0.086 ms > > 64 bytes from 10.0.0.2: icmp_seq=6 ttl=64 time=0.081 ms > > 64 bytes from 10.0.0.2: icmp_seq=7 ttl=64 time=0.086 ms > > 64 bytes from 10.0.0.2: icmp_seq=8 ttl=64 time=0.085 ms > > 64 bytes from 10.0.0.2: icmp_seq=9 ttl=64 time=0.085 ms > > 64 bytes from 10.0.0.2: icmp_seq=10 ttl=64 time=0.084 ms > > > > --- 10.0.0.2 ping statistics --- > > 10 packets transmitted, 10 received, 0% packet loss, time 9004ms > > rtt min/avg/max/mdev = 0.081/1.671/11.134/3.295 ms > Are their any existing or planned methods to ensure traffic from tenant ports is handled fairly, preventing traffic received on a single port from evicting flows from all other ports? Obviously uplink ports would need to be permitted a larger portion of flows. -Dustin [1] https://www.kernel.org/doc/Documentation/networking/pktgen.txt [2] https://github.com/dlundquist/openstack-scripts/blob/master/scripts/dp_test.sh ___ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev