Skip to content
Craig Riecke edited this page Jun 21, 2016 · 4 revisions

The NetKAT JSON syntax is used underneath the covers for the http-controller subcommand. The Frenetic Python library translates Python objects to REST/JSON calls to Frenetic. You can use REST/JSON from any other programming language to create your own bindings.

This syntax has the following benefits:

  • It's usable by any programming language that speaks REST and JSON
  • You can write dynamic programs with whatever native language constructs you feel comfortable with. Then simply convert them to JSON and REST to make Frenetic do the hard work.

And the following limitations:

  • JSON can be verbose

Only the NetKAT Syntax is presented here. See here for details on REST URL's in which to use these JSON objects.

Predicates

A predicate is a boolean condition for matching packets. It's generally used in filter and IfThenElse policies, outlined in the next section.

Special Primitives

Predicate Matches Packets With...
{"type":"false"} matches no packets
("type":"true"} matches all packets

Field Match Primitives

In JSON, the predicate looks like:

  { "type": "test", "header": "ethdst", "value": 12384671234 }

Values are generally strings or integers. The exception are ip4src and ip4dst which can be a single host or a network with a mask

  { "type": "test", "header": "ip4src", "value": {"addr":"192.168.56.123"} }
  { "type": "test", "header": "ip4src", "value": {"addr":"192.168.56.0", "mask":24} }

... and Location, which can reference a physical port:

  { "type": "test", "header": "location", "value": {"type":"physical", "port": 1} }
Header Matches Packets With...
ethdst Ethernet destination address: most common format is 6-byte colon-separated hex
ethsrc Ethernet source address
ethtype Ethernet type. For VLAN packets, this is the type of the inner packet, per OpenFlow 1.0
ip4dst IPv4 desintation address: see above for formats
ip4src IPv4 source address
ipproto IPv4 protocol number or ARP opcode. Must be decimal and fit in 16 bits.
location Ingress port number. See above for format. Must be less than 65520
switch Ingress switch datapath ID.
tcpsrcport TCP/UDP source port
tcpdstport TCP/UDP destination port.
vlan VLAN id.
vlanpcp VLAN PCP. priority code point.

Combinations

Predicate Matches Packets With...
{"type":"not", "pred": ... } the given predicate not matching
{"type":"and", "preds": [...] } all predicates matching
{"type":"or", "preds": [...] } one or more predicates matching

Policies

A NetKAT policy directs the switch to perform an action on a packet.

Special Primitives

Policy Does This With a Packet...
{"type":"filter", "pred":...} Accepts all packets that meet the predicate. Drops any other packets

Note that in a filter you can use the predicate {"type":"false"} to drop all packets or {"type":"true"} to accept all packets.

Header Setting Primitives

The format for setting a header is:

  { "type": "mod", "header": "ethdst", "value": 12384671234 }

And the header names are exactly those listed above in Field Match Primitives. The exceptions are:

  • switch cannot be used as a header
  • ip4src and ip4dst only accept a host without a net mask

In addition, there are several options for setting the location.

  { "type": "mod", "header": "location", "value": {"type":"physical", "port": 1} }
  { "type": "mod", "header": "location", "value": {"type":"query", "name": "tag"} }
  { "type": "mod", "header": "location", "value": {"type":"pipe", "name": "tag"} }

The first of these sends a packet to an egress port, the second to a statistics query bucket, the third to a controller. Note that a packet may only go to ONE of these destinations ... to send copies to more than on destination, use a Union combination.

Combinations

Policy Does This With a Packet...
{"type":"seq", "pols":[...]} Executes policies in sequence.
{"type":"union", "pols":[...]} Makes virtual copies of the packet and simultaneously executes all policies

Note there is no if-then-else construct, but you can construct it using the other combinations like this:

  { "type":"union", "pols":[
     { "type": "seq", "pols": [
        { "type": "filter", "pred": predicate },
        TruePolicy
     ]},
     { "type": "seq", "pols": [
        { "type": "filter", "pred": {
          {"type": "not", "pred": predicate }
        },
        FalsePolicy
     ]}
  ]}

Example

{
  "pols": [
    {
      "pols": [
        {
          "pred": {
            "header": "switch",
            "type": "test",
            "value": "1"
          },
          "type": "filter"
        },
        {
          "pols": [
            {
              "pols": [
                {
                  "pred": {
                    "header": "ethsrc",
                    "type": "test",
                    "value": "00:00:00:00:00:01"
                  },
                  "type": "filter"
                },
                {
                  "header": "location",
                  "type": "mod",
                  "value": {
                    "type": "physical",
                    "port": 1
                  }
                }
              ],
              "type": "seq"
            },
            {
              "pols": [
                {
                  "pred": {
                    "pred": {
                      "header": "ethsrc",
                      "type": "test",
                      "value": "00:00:00:00:00:01"
                    },
                    "type": "neg"
                  },
                  "type": "filter"
                },
                {
                  "pols": [
                    {
                      "pols": [
                        {
                          "pred": {
                            "header": "ethsrc",
                            "type": "test",
                            "value": "00:00:00:00:00:02"
                          },
                          "type": "filter"
                        },
                        {
                          "header": "location",
                          "type": "mod",
                          "value": {
                            "type": "physical",
                            "port": 2
                          }
                        }
                      ],
                      "type": "seq"
                    },
                    {
                      "pols": [
                        {
                          "pred": {
                            "pred": {
                              "header": "ethsrc",
                              "type": "test",
                              "value": "00:00:00:00:00:02"
                            },
                            "type": "neg"
                          },
                          "type": "filter"
                        },
                        {
                          "pols": [
                            {
                              "pols": [
                                {
                                  "pred": {
                                    "header": "ethsrc",
                                    "type": "test",
                                    "value": "00:00:00:00:00:03"
                                  },
                                  "type": "filter"
                                },
                                {
                                  "header": "location",
                                  "type": "mod",
                                  "value": {
                                    "type": "physical",
                                    "port": 3
                                  }
                                }
                              ],
                              "type": "seq"
                            },
                            {
                              "pols": [
                                {
                                  "pred": {
                                    "pred": {
                                      "header": "ethsrc",
                                      "type": "test",
                                      "value": "00:00:00:00:00:03"
                                    },
                                    "type": "neg"
                                  },
                                  "type": "filter"
                                },
                                {
                                  "header": "location",
                                  "type": "mod",
                                  "value": {
                                    "type": "physical",
                                    "port": 4
                                  }
                                }
                              ],
                              "type": "seq"
                            }
                          ],
                          "type": "union"
                        }
                      ],
                      "type": "seq"
                    }
                  ],
                  "type": "union"
                }
              ],
              "type": "seq"
            }
          ],
          "type": "union"
        }
      ],
      "type": "seq"
    },
    {
      "pols": [
        {
          "pred": {
            "header": "switch",
            "type": "test",
            "value": "2"
          },
          "type": "filter"
        },
        {
          "pols": [
            {
              "pols": [
                {
                  "pols": [
                    {
                      "pred": {
                        "preds": [
                          {
                            "header": "ethtype",
                            "type": "test",
                            "value": 2048
                          },
                          {
                            "header": "ip4src",
                            "type": "test",
                            "value": {
                              "mask": 32,
                              "addr": "192.168.0.1"
                            }
                          }
                        ],
                        "type": "and"
                      },
                      "type": "filter"
                    },
                    {
                      "header": "location",
                      "type": "mod",
                      "value": {
                        "type": "physical",
                        "port": 1
                      }
                    }
                  ],
                  "type": "seq"
                },
                {
                  "pols": [
                    {
                      "pred": {
                        "preds": [
                          {
                            "header": "ethtype",
                            "type": "test",
                            "value": 2048
                          },
                          {
                            "header": "ip4src",
                            "type": "test",
                            "value": {
                              "mask": 32,
                              "addr": "192.168.0.2"
                            }
                          }
                        ],
                        "type": "and"
                      },
                      "type": "filter"
                    },
                    {
                      "header": "location",
                      "type": "mod",
                      "value": {
                        "type": "physical",
                        "port": 2
                      }
                    }
                  ],
                  "type": "seq"
                }
              ],
              "type": "union"
            },
            {
              "pols": [
                {
                  "pred": {
                    "preds": [
                      {
                        "header": "ethtype",
                        "type": "test",
                        "value": 2048
                      },
                      {
                        "header": "ip4src",
                        "type": "test",
                        "value": {
                          "mask": 32,
                          "addr": "192.168.0.3"
                        }
                      }
                    ],
                    "type": "and"
                  },
                  "type": "filter"
                },
                {
                  "header": "location",
                  "type": "mod",
                  "value": {
                    "type": "physical",
                    "port": 3
                  }
                }
              ],
              "type": "seq"
            }
          ],
          "type": "union"
        }
      ],
      "type": "seq"
    }
  ],
  "type": "union"
}