Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement Everything #267

Merged
merged 54 commits into from
Mar 2, 2014
Merged

Implement Everything #267

merged 54 commits into from
Mar 2, 2014

Conversation

seliopou
Copy link
Collaborator

@seliopou seliopou commented Mar 1, 2014

This pull request subsumes #253 and #256, and implements additional functionality. Specifically, it:

  • defines an Frenetic application API
  • implements an async-based controller against that API
  • enabled writing policies with pipes, i.e., named controller locations
  • implements packet-in dispatch to applications, which involves running part of the policy on the controller
  • provides baked-in topology discovery as a frenetic application (can be easily removed)
  • provides a learning switch demo app

seliopou and others added 30 commits February 17, 2014 17:17
portId is currently a synonym for a VInt.t but that will likely change
at some point to be a synonym for int64. Use the type consistently here,
which may save time later.
This commit includes two important type definitions:

  * event - describes the types of events that frenetic applications
    will be exposed to, and will be expected to handle in some way.

  * result - the ultimate result of a frenetic application. A list of
    packet_outs to send to various switches, as well as the new policy
    that should be installed on those switches. It's on this type that
    sequence and union will be defined, and then lifted to a function type.
For all intents and purposes, Async_NetKAT.mli is a specification of the
Frenetic application API.

Closes #244.
The name did not imply that there was anything else being sequenced. Now
it implies that after the action, the type of the module the function
belongs to is also being sequenced.
matches determines whether or not some pattern-like structure matches a
given packet.
from_pipe takes a Local.t, which a controller may cache per switch, and
a packet, and determines the pipe that the packet belongs to. In general
this is not always possible. For a brief interval during switch setup,
packets may be sent to the controller not due to a policy. If a policy
makes use of different pipe name in non-disjoint parallel compositions,
then it may come from either, in which case the pipe the packet belongs
to is ambiguous.
The user may have composed two applications that are interested in
packets that match identical filters, but are sent to different pipes.
from_pipe must account for this, and therefore return all pipes that
match the packet. It is the job of the runtime to then deliver the
packets to the proper pipe within the application, when possible.
(cherry picked from commit 434b1f8)
The from_pipes function now assumes that packets are not modified on the
switch before being sent to the controller. That means that any
modification of a field preceding a "port := <pipe>" is ignored for the
purposes of compilation, and implemented at the controller.
Not sure why the code was clearing it before.
Any action that involves "port := <pipe>" should skip all other
modifications, and send the packet straight to the controller. The
skipped modifications will be applied there.
Skip filters that match on pipes.
When the controller receives a packet, it uses a cached representation
of the policy installed on the switch to determine which pipe it should
be sent to.
Previously called from_pipes. This function will evaluate a packet on a
switch's policy, returning two lists. The first contains pairs of pipe
names and modified packets. These will be sent to listening
applications. The second is a list of modified packets. These will be
used to generate packet out messages.
When a packet arrives at the controller, it's eval'd given the policy
currently installed on the switch. If that produces packets located at
physical locations, the controller will generate packet outs that will
perform the appropriate modifications in the form of actions.

Previously, the packet was not modified and no actions were inclued with
the packet_out.
Was actually setting vlanPcp
Due to the flattening of seqs that involve Controller actions, this
function may now produce duplicates. So, deduplicate. This approach does
not preserve the order of the pars.
Right now, the compiler will not generates rules to modify packets if
they'll ultimately be sent to the controller. It's up to the controller
to implement those changes, which must happen before passing packets to
the application.
The port optional port in a OFPT_PACKET_OUT is only used when the action
list contains an action that would send the packet to the TABLE
pseudoport. As of now, Frenetic does not allow this.
If a branch of a union has side-effects, the user may want to ensure their
ordering by using `Sequential, which will evaluate the left application to
completion before running the right one. `Parallel provides no guarantee about
evaluation order.
This reverts commit 8ba2bd0.

Conflicts:
	lib/NetKAT_Types.ml
Fill out the rest of the topology events. These have some overlap. For
example, the user will see a PortUp event as well as a LinkUp event
containing the same switch_endpoint. It's up to each application to
decide what level of detail they want to observe, and ignore the rest.
Use a custom instance of Network and stop using the topology disocvery
stage from ocaml-openflow.
Asserts seem to not play nicely with async.
The unit argument indicates a partial application point. Anything
computed in the partial application not be recomputed on applications of
subsequent arguments.
Conflicts:
	_tags
	lib/LocalCompiler.ml
	lib/NetKAT_Types.ml
	lib/Semantics.ml
	lib/netcore.mllib
	setup.ml
Move the creation of the event pipes to Ctl, and expose a functions to
use it, as well as query to state of pending ports.
The Discovery.Host app will copy all arp traffic and send it to the
controller. It assumes that the entire network is under the management
of the controller.
The events written to the pipe will eventually get fed back into the
app, so blocking on pushback was causing a deadlock.
@jnfoster
Copy link
Member

jnfoster commented Mar 1, 2014

Officially an "epic" pull request.

@arjunguha
Copy link
Member

I ran $ sudo mn --controller=remote --topo=tree,2,2 and in another terminal got this error:

$ ./katnetic.byte run local examples/tree-2-2.kat 
(lib/typed_tcp.ml.Make.Connection_closed
  lib/typed_tcp.ml.Make.Eof_from_client)
 [INFO] [topology.switch] ↑ { switch = 1 }
[ERROR] switch 1: Failed to update table
 [INFO] [topology.switch] ↑ { switch = 1; port = 2 }
[ERROR] switch 1: Failed to send packet_out
 [INFO] [topology.switch] ↑ { switch = 1; port = 1 }
[ERROR] switch 1: Failed to send packet_out
[ERROR] switch 1: Failed to send packet_out
[ERROR] switch 1: Failed to send packet_out
[ERROR] switch 1: Failed to send packet_out
(lib/typed_tcp.ml.Make.Connection_closed
  lib/typed_tcp.ml.Make.Eof_from_client)
 [INFO] [learning] switch 1: learn 42:3c:a5:a9:17:5e => 1@1
 [INFO] [learning] switch 1: flood dlSrc=42:3c:a5:a9:17:5e,dlDst=33:33:ff:a9:17:5e,frameType=0x86DD
[ERROR] switch 1: Failed to send packet_out
[ERROR] switch 1: Failed to send packet_out
("unhandled exception"
 ((lib/monitor.ml.Error_
   ((exn (lib/typed_tcp.ml.Make.Missing_client_id 2))
    (backtrace
     ("Raised at file \"async/Async_OpenFlowChunk.ml\", line 50, characters 27-30"
      "Called from file \"lib/deferred.ml\", line 12, characters 64-67"
      "Called from file \"lib/jobs.ml\", line 216, characters 10-13" ""))
    (monitor
     (((name Monitor.protect) (here ()) (id 8) (has_seen_error true)
       (someone_is_listening true) (kill_index 0))))))
  (Pid 2071)))

It seems to be reproducible. Any ideas?

@seliopou
Copy link
Collaborator Author

seliopou commented Mar 1, 2014

A few things to try:

  1. Make sure that mininet's properly cleaned up and you're starting fresh. Run sudo mn -c and check to make sure there are no zombie processes.
  2. Are you using the current HEAD of ocaml-openflow?
  3. While it print out errors, it may still be in working order. Did you check for connectivity?
  4. Instead of using examples/tree-2-2.kat can you try with a static policy consisting of drop and nothing else?

@seliopou
Copy link
Collaborator Author

seliopou commented Mar 1, 2014

Also, note that in order for the policy to work you shoud run mn with the --mac option as well.

@arjunguha
Copy link
Member

Ah. I think it has to do with the sizes we use for ports and switches. The
static policy uses older sizes, I think. Investigating.

On Sat, Mar 1, 2014 at 4:11 PM, Spiros Eliopoulos
[email protected]:

Also, note that in order for the policy to work you shoud run mn with the
--mac option as well.


Reply to this email directly or view it on GitHubhttps://github.com//pull/267#issuecomment-36436804
.

@arjunguha
Copy link
Member

I'm getting the error here:

https://github.com/frenetic-lang/ocaml-openflow/blob/master/lib/VInt.ml#L23

With a little more debugging output, it prints the following:

[ERROR] switch 3: Failed to send packet_out ((lib/monitor.ml.Error_
  ((exn (Invalid_argument "get_int (Int32 2)"))
    (backtrace
      ("Raised at file \"lib/VInt.ml\", line 23, characters 15-65"
        "Called from file \"async/Async_NetKAT_Controller.ml\", line 140, characters 23-38"
...

From my console:

$ ocaml
        OCaml version 4.01.0

# 2l > Int32.of_int max_int;;
- : bool = true
# max_int;;
- : int = 4611686018427387903
# Int32.of_int max_int;;
- : int32 = -1l
# 

Can anyone else reproduce this?

@arjunguha
Copy link
Member

Wait, this is obviously bogus. I'm on a 64-bit platform.

Besides, all these overflow checks should just use Int32.max_int, Int64.max_int, etc.

@arjunguha
Copy link
Member

How has this not affected anyone else? Is everyone else using a 32-bit platform?

@seliopou
Copy link
Collaborator Author

seliopou commented Mar 1, 2014

Yes, this is a known issue. See frenetic-lang/ocaml-openflow#105. It needs to be fixed for the next release. Maybe everybody's still developing on the frenetic vm, which was 32-bit?

@arjunguha arjunguha merged commit a6e6268 into master Mar 2, 2014
@jnfoster
Copy link
Member

jnfoster commented Mar 2, 2014

Huzzah!

@seliopou seliopou deleted the topo branch March 2, 2014 06:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants