Developer documentation

* Turns TESTING into a rst file, that we include in the developer
  documentation, for instructions on how to run the unit tests.
* Link to a Vagrant project that sets up Neutron inside a VM.
* Adds a section for how to debug with Nose
* Add new section for Neutron Internals
* Neutron L2 Agent documentation - currently only OVS
* Make the Security Group API extension an example of how an API
  extension is implemented

Implements bp developer-documentation

Change-Id: I9b452abc9da3b1a41ae65cff727967de0eab12fe
This commit is contained in:
Sean M. Collins 2014-01-31 14:38:33 -05:00
parent 0d78a25ffb
commit 72398f1f69
14 changed files with 506 additions and 160 deletions

100
TESTING
View File

@ -1,100 +0,0 @@
Testing Neutron
=============================================================
Overview
The unit tests are meant to cover as much code as possible and should
be executed without the service running. They are designed to test
the various pieces of the neutron tree to make sure any new changes
don't break existing functionality.
The functional tests are intended to validate actual system
interaction. Mocks should be used sparingly, if at all. Care
should be taken to ensure that existing system resources are not
modified and that resources created in tests are properly cleaned
up.
Running tests
There are two mechanisms for running tests: run_tests.sh and tox.
Before submitting a patch for review you should always ensure all
test pass; a tox run is triggered by the jenkins gate executed on
gerrit for each patch pushed for review.
With both mechanisms you can either run the tests in the standard
environment or create a virtual environment to run them in.
By default after running all of the tests, any pep8 errors
found in the tree will be reported.
Running individual tests
For running individual test modules or cases, you just need to pass
the dot-separated path to the module you want as an argument to it.
For executing a specific test case, specify the name of the test case
class separating it from the module path with a colon.
For example, the following would run only the JSONV2TestCase tests from
neutron/tests/unit/test_api_v2.py:
$ ./run_tests.sh neutron.tests.unit.test_api_v2:JSONV2TestCase
or
$ ./tox neutron.tests.unit.test_api_v2:JSONV2TestCase
Adding more tests
Neutron has a fast growing code base and there is plenty of areas that
need to be covered by unit and functional tests.
To get a grasp of the areas where tests are needed, you can check
current coverage by running:
$ ./run_tests.sh -c
Development process
It is expected that any new changes that are proposed for merge
come with tests for that feature or code area. Ideally any bugs
fixes that are submitted also have tests to prove that they stay
fixed! In addition, before proposing for merge, all of the
current tests should be passing.
Debugging
By default, calls to pdb.set_trace() will be ignored when tests
are run. For pdb statements to work, invoke run_tests as follows:
$ ./run_tests.sh -d [test module path]
It's possible to debug tests in a tox environment:
$ tox -e venv -- python -m testtools.run [test module path]
Tox-created virtual environments (venv's) can also be activated
after a tox run and reused for debugging:
$ tox -e venv
$ . .tox/venv/bin/activate
$ python -m testtools.run [test module path]
Tox packages and installs the neutron source tree in a given venv
on every invocation, but if modifications need to be made between
invocation (e.g. adding more pdb statements), it is recommended
that the source tree be installed in the venv in editable mode:
# run this only after activating the venv
$ pip install --editable .
Editable mode ensures that changes made to the source tree are
automatically reflected in the venv, and that such changes are not
overwritten during the next tox run.
Post-mortem debugging
Setting OS_POST_MORTEM_DEBUG=1 in the shell environment will ensure
that pdb.post_mortem() will be invoked on test failure:
$ OS_POST_MORTEM_DEBUG=1 ./run_tests.sh -d [test module path]

180
TESTING.rst Normal file
View File

@ -0,0 +1,180 @@
Testing Neutron
=============================================================
Overview
--------
The unit tests are meant to cover as much code as possible and should
be executed without the service running. They are designed to test
the various pieces of the neutron tree to make sure any new changes
don't break existing functionality.
The functional tests are intended to validate actual system
interaction. Mocks should be used sparingly, if at all. Care
should be taken to ensure that existing system resources are not
modified and that resources created in tests are properly cleaned
up.
Development process
-------------------
It is expected that any new changes that are proposed for merge
come with tests for that feature or code area. Ideally any bugs
fixes that are submitted also have tests to prove that they stay
fixed! In addition, before proposing for merge, all of the
current tests should be passing.
Virtual environments
~~~~~~~~~~~~~~~~~~~~
Testing OpenStack projects, including Neutron, is made easier with `DevStack <https://github.com/openstack-dev/devstack>`_.
Create a machine (such as a VM or Vagrant box) running a distribution supported
by DevStack and install DevStack there. For example, there is a Vagrant script
for DevStack at https://github.com/bcwaldon/vagrant_devstack.
.. note::
If you prefer not to use DevStack, you can still check out source code on your local
machine and develop from there.
Running unit tests
------------------
There are three mechanisms for running tests: run_tests.sh, tox,
and nose. Before submitting a patch for review you should always
ensure all test pass; a tox run is triggered by the jenkins gate
executed on gerrit for each patch pushed for review.
With these mechanisms you can either run the tests in the standard
environment or create a virtual environment to run them in.
By default after running all of the tests, any pep8 errors
found in the tree will be reported.
With `run_tests.sh`
~~~~~~~~~~~~~~~~~~~
You can use the `run_tests.sh` script in the root source directory to execute
tests in a virtualenv::
./run_tests -V
With `nose`
~~~~~~~~~~~
You can use `nose`_ to run individual tests, as well as use for debugging
portions of your code::
source .venv/bin/activate
pip install nose
nosetests
There are disadvantages to running Nose - the tests are run sequentially, so
race condition bugs will not be triggered, and the full test suite will
take significantly longer than tox & testr. The upside is that testr has
some rough edges when it comes to diagnosing errors and failures, and there is
no easy way to set a breakpoint in the Neutron code, and enter an
interactive debugging session while using testr.
.. _nose: https://nose.readthedocs.org/en/latest/index.html
With `tox`
~~~~~~~~~~
Neutron, like other OpenStack projects, uses `tox`_ for managing the virtual
environments for running test cases. It uses `Testr`_ for managing the running
of the test cases.
Tox handles the creation of a series of `virtualenvs`_ that target specific
versions of Python (2.6, 2.7, 3.3, etc).
Testr handles the parallel execution of series of test cases as well as
the tracking of long-running tests and other things.
Running unit tests is as easy as executing this in the root directory of the
Neutron source code::
tox
For more information on the standard Tox-based test infrastructure used by
OpenStack and how to do some common test/debugging procedures with Testr,
see this wiki page:
https://wiki.openstack.org/wiki/Testr
.. _Testr: https://wiki.openstack.org/wiki/Testr
.. _tox: http://tox.readthedocs.org/en/latest/
.. _virtualenvs: https://pypi.python.org/pypi/virtualenv
Running individual tests
~~~~~~~~~~~~~~~~~~~~~~~~
For running individual test modules or cases, you just need to pass
the dot-separated path to the module you want as an argument to it.
For executing a specific test case, specify the name of the test case
class separating it from the module path with a colon.
For example, the following would run only the JSONV2TestCase tests from
neutron/tests/unit/test_api_v2.py::
$ ./run_tests.sh neutron.tests.unit.test_api_v2:JSONV2TestCase
or::
$ ./tox neutron.tests.unit.test_api_v2:JSONV2TestCase
Adding more tests
~~~~~~~~~~~~~~~~~
Neutron has a fast growing code base and there is plenty of areas that
need to be covered by unit and functional tests.
To get a grasp of the areas where tests are needed, you can check
current coverage by running::
$ ./run_tests.sh -c
Debugging
---------
By default, calls to pdb.set_trace() will be ignored when tests
are run. For pdb statements to work, invoke run_tests as follows::
$ ./run_tests.sh -d [test module path]
It's possible to debug tests in a tox environment::
$ tox -e venv -- python -m testtools.run [test module path]
Tox-created virtual environments (venv's) can also be activated
after a tox run and reused for debugging::
$ tox -e venv
$ . .tox/venv/bin/activate
$ python -m testtools.run [test module path]
Tox packages and installs the neutron source tree in a given venv
on every invocation, but if modifications need to be made between
invocation (e.g. adding more pdb statements), it is recommended
that the source tree be installed in the venv in editable mode::
# run this only after activating the venv
$ pip install --editable .
Editable mode ensures that changes made to the source tree are
automatically reflected in the venv, and that such changes are not
overwritten during the next tox run.
Post-mortem debugging
~~~~~~~~~~~~~~~~~~~~~
Setting OS_POST_MORTEM_DEBUG=1 in the shell environment will ensure
that pdb.post_mortem() will be invoked on test failure::
$ OS_POST_MORTEM_DEBUG=1 ./run_tests.sh -d [test module path]

View File

@ -0,0 +1,18 @@
==============
API Extensions
==============
API extensions is the standard way of introducing new functionality
to the Neutron project, it allows plugins to
determine if they wish to support the functionality or not.
Examples
========
The easiest way to demonstrate how an API extension is written, is
by studying an existing API extension and explaining the different layers.
.. toctree::
:maxdepth: 1
security_group_api

View File

@ -0,0 +1,4 @@
Neutron WSGI/HTTP API layer
===========================
`Yong Sheng Gong: Deep Dive into Neutron <http://www.slideshare.net/gongys2004/inside-neutron-2>`_

View File

@ -0,0 +1,2 @@
Neutron Database Layer
======================

View File

@ -37,20 +37,6 @@ that describes `setting up Neutron using DevStack`_.
.. _DevStack: https://github.com/openstack-dev/devstack
.. _setting up Neutron using Devstack: https://wiki.openstack.org/wiki/NeutronDevstack
Virtual environments
--------------------
Testing OpenStack projects, including Neutron, is made easier with `DevStack`_.
Create a machine (such as a VM or Vagrant box) running a distribution supported
by DevStack and install DevStack there. For example, there is a Vagrant script
for DevStack at https://github.com/jogo/DevstackUp.
.. note::
If you prefer not to use DevStack, you can still check out source code on your local
machine and develop from there.
Getting the code
----------------
@ -60,48 +46,4 @@ Grab the code from GitHub::
cd neutron
Running unit tests
------------------
With `run_tests.sh`
~~~~~~~~~~~~~~~~~~~
You can use the `run_tests.sh` script in the root source directory to execute
tests in a virtualenv:
./run_tests -V
With `tox`
~~~~~~~~~~
Neutron, like other OpenStack projects, uses `tox`_ for managing the virtual
environments for running test cases. It uses `Testr`_ for managing the running
of the test cases.
Tox handles the creation of a series of `virtualenvs`_ that target specific
versions of Python (2.6, 2.7, 3.3, etc).
Testr handles the parallel execution of series of test cases as well as
the tracking of long-running tests and other things.
Running unit tests is as easy as executing this in the root directory of the
Neutron source code::
tox
For more information on the standard Tox-based test infrastructure used by
OpenStack and how to do some common test/debugging procedures with Testr,
see this wiki page:
https://wiki.openstack.org/wiki/Testr
.. _Testr: https://wiki.openstack.org/wiki/Testr
.. _tox: http://tox.readthedocs.org/en/latest/
.. _virtualenvs: https://pypi.python.org/pypi/virtualenv
Using a remote debugger
-----------------------
.. todo:: Beef up and add examples to content at
https://wiki.openstack.org/wiki/NeutronDevelopment#How_to_debug_Neutron_.28and_other_OpenStack_projects_probably_.29
.. include:: ../../../TESTING.rst

View File

@ -32,6 +32,20 @@ Programming HowTos and Tutorials
development.environment
Neutron Internals
-----------------
.. toctree::
:maxdepth: 3
api_layer
api_extensions
plugin-api
db_layer
rpc_api
layer3
l2_agents
Module Reference
----------------
.. toctree::

View File

@ -0,0 +1,7 @@
L2 Agent Networking
-------------------
.. toctree::
:maxdepth: 3
openvswitch_agent
linuxbridge_agent

View File

@ -0,0 +1,199 @@
Layer 3 Networking in Neutron - via Layer 3 agent & OpenVSwitch
===============================================================
This page discusses the usage of Neutron with Layer 3 functionality enabled.
Neutron logical network setup
-----------------------------
::
vagrant@precise64:~/devstack$ neutron net-list
+--------------------------------------+---------+--------------------------------------------------+
| id | name | subnets |
+--------------------------------------+---------+--------------------------------------------------+
| 84b6b0cc-503d-448a-962f-43def05e85be | public | 3a56da7c-2f6e-41af-890a-b324d7bc374d |
| a4b4518c-800d-4357-9193-57dbb42ac5ee | private | 1a2d26fb-b733-4ab3-992e-88554a87afa6 10.0.0.0/24 |
+--------------------------------------+---------+--------------------------------------------------+
vagrant@precise64:~/devstack$ neutron subnet-list
+--------------------------------------+------+-------------+--------------------------------------------+
| id | name | cidr | allocation_pools |
+--------------------------------------+------+-------------+--------------------------------------------+
| 1a2d26fb-b733-4ab3-992e-88554a87afa6 | | 10.0.0.0/24 | {"start": "10.0.0.2", "end": "10.0.0.254"} |
+--------------------------------------+------+-------------+--------------------------------------------+
vagrant@precise64:~/devstack$ neutron port-list
+--------------------------------------+------+-------------------+---------------------------------------------------------------------------------+
| id | name | mac_address | fixed_ips |
+--------------------------------------+------+-------------------+---------------------------------------------------------------------------------+
| 0ba8700e-da06-4318-8fe9-00676dd994b8 | | fa:16:3e:78:43:5b | {"subnet_id": "1a2d26fb-b733-4ab3-992e-88554a87afa6", "ip_address": "10.0.0.1"} |
| b2044570-ad52-4f31-a2c3-5d767dc9a8a7 | | fa:16:3e:5b:cf:4c | {"subnet_id": "1a2d26fb-b733-4ab3-992e-88554a87afa6", "ip_address": "10.0.0.3"} |
| bb60d1bb-0cab-41cb-9678-30d2b2fdb169 | | fa:16:3e:af:a9:bd | {"subnet_id": "1a2d26fb-b733-4ab3-992e-88554a87afa6", "ip_address": "10.0.0.2"} |
+--------------------------------------+------+-------------------+---------------------------------------------------------------------------------+
vagrant@precise64:~/devstack$ neutron subnet-show 1a2d26fb-b733-4ab3-992e-88554a87afa6
+------------------+--------------------------------------------+
| Field | Value |
+------------------+--------------------------------------------+
| allocation_pools | {"start": "10.0.0.2", "end": "10.0.0.254"} |
| cidr | 10.0.0.0/24 |
| dns_nameservers | |
| enable_dhcp | True |
| gateway_ip | 10.0.0.1 |
| host_routes | |
| id | 1a2d26fb-b733-4ab3-992e-88554a87afa6 |
| ip_version | 4 |
| name | |
| network_id | a4b4518c-800d-4357-9193-57dbb42ac5ee |
| tenant_id | 3368290ab10f417390acbb754160dbb2 |
+------------------+--------------------------------------------+
Neutron logical router setup
----------------------------
* http://docs.openstack.org/admin-guide-cloud/content/ch_networking.html#under_the_hood_openvswitch_scenario1_network
::
vagrant@precise64:~/devstack$ neutron router-list
+--------------------------------------+---------+--------------------------------------------------------+
| id | name | external_gateway_info |
+--------------------------------------+---------+--------------------------------------------------------+
| 569469c7-a2a5-4d32-9cdd-f0b18a13f45e | router1 | {"network_id": "84b6b0cc-503d-448a-962f-43def05e85be"} |
+--------------------------------------+---------+--------------------------------------------------------+
vagrant@precise64:~/devstack$ neutron router-show router1
+-----------------------+--------------------------------------------------------+
| Field | Value |
+-----------------------+--------------------------------------------------------+
| admin_state_up | True |
| external_gateway_info | {"network_id": "84b6b0cc-503d-448a-962f-43def05e85be"} |
| id | 569469c7-a2a5-4d32-9cdd-f0b18a13f45e |
| name | router1 |
| routes | |
| status | ACTIVE |
| tenant_id | 3368290ab10f417390acbb754160dbb2 |
+-----------------------+--------------------------------------------------------+
vagrant@precise64:~/devstack$ neutron router-port-list router1
+--------------------------------------+------+-------------------+---------------------------------------------------------------------------------+
| id | name | mac_address | fixed_ips |
+--------------------------------------+------+-------------------+---------------------------------------------------------------------------------+
| 0ba8700e-da06-4318-8fe9-00676dd994b8 | | fa:16:3e:78:43:5b | {"subnet_id": "1a2d26fb-b733-4ab3-992e-88554a87afa6", "ip_address": "10.0.0.1"} |
+--------------------------------------+------+-------------------+---------------------------------------------------------------------------------+
Neutron Routers are realized in OpenVSwitch
-------------------------------------------
.. image:: http://docs.openstack.org/admin-guide-cloud/content/figures/10/a/common/figures/under-the-hood-scenario-1-ovs-network.png
"router1" in the Neutron logical network is realized through a port ("qr-0ba8700e-da") in OpenVSwitch - attached to "br-int"::
vagrant@precise64:~/devstack$ sudo ovs-vsctl show
b9b27fc3-5057-47e7-ba64-0b6afe70a398
Bridge br-int
Port "qr-0ba8700e-da"
tag: 1
Interface "qr-0ba8700e-da"
type: internal
Port br-int
Interface br-int
type: internal
Port int-br-ex
Interface int-br-ex
Port "tapbb60d1bb-0c"
tag: 1
Interface "tapbb60d1bb-0c"
type: internal
Port "qvob2044570-ad"
tag: 1
Interface "qvob2044570-ad"
Port "int-br-eth1"
Interface "int-br-eth1"
Bridge "br-eth1"
Port "phy-br-eth1"
Interface "phy-br-eth1"
Port "br-eth1"
Interface "br-eth1"
type: internal
Bridge br-ex
Port phy-br-ex
Interface phy-br-ex
Port "qg-0143bce1-08"
Interface "qg-0143bce1-08"
type: internal
Port br-ex
Interface br-ex
type: internal
ovs_version: "1.4.0+build0"
vagrant@precise64:~/devstack$ brctl show
bridge name bridge id STP enabled interfaces
br-eth1 0000.e2e7fc5ccb4d no
br-ex 0000.82ee46beaf4d no phy-br-ex
qg-39efb3f9-f0
qg-77e0666b-cd
br-int 0000.5e46cb509849 no int-br-ex
qr-54c9cd83-43
qvo199abeb2-63
qvo1abbbb60-b8
tap74b45335-cc
qbr199abeb2-63 8000.ba06e5f8675c no qvb199abeb2-63
tap199abeb2-63
qbr1abbbb60-b8 8000.46a87ed4fb66 no qvb1abbbb60-b8
tap1abbbb60-b8
virbr0 8000.000000000000 yes
Finding the router in ip/ipconfig
---------------------------------
* http://docs.openstack.org/admin-guide-cloud/content/ch_networking.html
The neutron-l3-agent uses the Linux IP stack and iptables to perform L3 forwarding and NAT.
In order to support multiple routers with potentially overlapping IP addresses, neutron-l3-agent
defaults to using Linux network namespaces to provide isolated forwarding contexts. As a result,
the IP addresses of routers will not be visible simply by running "ip addr list" or "ifconfig" on
the node. Similarly, you will not be able to directly ping fixed IPs.
To do either of these things, you must run the command within a particular router's network
namespace. The namespace will have the name "qrouter-<UUID of the router>.
.. image:: http://docs.openstack.org/admin-guide-cloud/content/figures/10/a/common/figures/under-the-hood-scenario-1-ovs-netns.png
For example::
vagrant@precise64:~$ neutron router-list
+--------------------------------------+---------+--------------------------------------------------------+
| id | name | external_gateway_info |
+--------------------------------------+---------+--------------------------------------------------------+
| ad948c6e-afb6-422a-9a7b-0fc44cbb3910 | router1 | {"network_id": "e6634fef-03fa-482a-9fa7-e0304ce5c995"} |
+--------------------------------------+---------+--------------------------------------------------------+
vagrant@precise64:~/devstack$ sudo ip netns exec qrouter-ad948c6e-afb6-422a-9a7b-0fc44cbb3910 ip addr list
18: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
19: qr-54c9cd83-43: <BROADCAST,MULTICAST,PROMISC,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN
link/ether fa:16:3e:dd:c1:8f brd ff:ff:ff:ff:ff:ff
inet 10.0.0.1/24 brd 10.0.0.255 scope global qr-54c9cd83-43
inet6 fe80::f816:3eff:fedd:c18f/64 scope link
valid_lft forever preferred_lft forever
20: qg-77e0666b-cd: <BROADCAST,MULTICAST,PROMISC,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN
link/ether fa:16:3e:1f:d3:ec brd ff:ff:ff:ff:ff:ff
inet 192.168.27.130/28 brd 192.168.27.143 scope global qg-77e0666b-cd
inet6 fe80::f816:3eff:fe1f:d3ec/64 scope link
valid_lft forever preferred_lft forever
Provider Networking
-------------------
Neutron can also be configured to create `provider networks <http://docs.openstack.org/admin-guide-cloud/content/ch_networking.html#provider_terminology>`_
Further Reading
---------------
* `Packet Pushers - Neutron Network Implementation on Linux <http://packetpushers.net/openstack-neutron-network-implementation-in-linux/>`_
* `OpenStack Cloud Administrator Guide <http://docs.openstack.org/admin-guide-cloud/content/ch_networking.html>`_
* `Neutron - Layer 3 API extension usage guide <http://docs.openstack.org/api/openstack-network/2.0/content/router_ext.html>`_
* `Darragh O'Reilly - The Quantum L3 router and floating IPs <http://techbackground.blogspot.com/2013/05/the-quantum-l3-router-and-floating-ips.html>`_

View File

@ -0,0 +1,2 @@
L2 Networking with Linux Bridge
-------------------------------

View File

@ -0,0 +1,21 @@
====================
OpenVSwitch L2 Agent
====================
This Agent uses the `OpenVSwitch`_ virtual switch to create L2
connectivity for instances, along with bridges created in conjunction
with OpenStack Nova for filtering.
ovs-neutron-agent can be configured to use two different networking technologies to create tenant isolation, either GRE tunnels or VLAN tags.
VLAN Tags
---------
.. image:: http://docs.openstack.org/admin-guide-cloud/content/figures/10/a/common/figures/under-the-hood-scenario-1-ovs-compute.png
.. _OpenVSwitch: http://openvswitch.org
Further Reading
---------------
* `Darragh O'Reilly - The Open vSwitch plugin with VLANs <http://techbackground.blogspot.com/2013/07/the-open-vswitch-plugin-with-vlans.html>`_

View File

@ -1,5 +1,10 @@
Neutron Plugin Architecture
===========================
`Salvatore Orlando: How to write a Neutron Plugin (if you really need to) <http://www.slideshare.net/salv_orlando/how-to-write-a-neutron-plugin-if-you-really-need-to>`_
Plugin API
==========
----------
.. automodule:: neutron.neutron_plugin_base_v2

View File

@ -0,0 +1,2 @@
Neutron RCP API Layer
=====================

View File

@ -0,0 +1,50 @@
Guided Tour: The Neutron Security Group API
===========================================
https://wiki.openstack.org/wiki/Neutron/SecurityGroups
API Extension
-------------
The API extension is the 'front' end portion of the code, which handles defining a `REST-ful API`_, which is used by tenants.
.. _`REST-ful API`: https://github.com/openstack/neutron/blob/master/neutron/extensions/securitygroup.py
Database API
------------
The Security Group API extension adds a number of `methods to the database layer`_ of Neutron
.. _`methods to the database layer`: https://github.com/openstack/neutron/blob/master/neutron/db/securitygroups_db.py
Agent RPC
---------
This portion of the code handles processing requests from tenants, after they have been stored in the database. It involves messaging all the L2 agents
running on the compute nodes, and modifying the IPTables rules on each hypervisor.
* `Plugin RPC classes <https://github.com/openstack/neutron/blob/master/neutron/db/securitygroups_rpc_base.py>`_
* `SecurityGroupServerRpcCallbackMixin <https://github.com/openstack/neutron/blob/master/neutron/db/securitygroups_rpc_base.py#L126>`_ - defines the RPC API that the plugin uses to communicate with the agents running on the compute nodes
* SecurityGroupServerRpcMixin - Defines the API methods used to fetch data from the database, in order to return responses to agents via the RPC API
* `Agent RPC classes <https://github.com/openstack/neutron/blob/master/neutron/agent/securitygroups_rpc.py>`_
* The SecurityGroupServerRpcApiMixin defines the API methods that can be called by agents, back to the plugin that runs on the Neutron controller
* The SecurityGroupAgentRpcCallbackMixin defines methods that a plugin uses to call back to an agent after performing an action called by an agent.
IPTables Driver
---------------
* ``prepare_port_filter`` takes a ``port`` argument, which is a ``dictionary`` object that contains information about the port - including the ``security_group_rules``
* ``prepare_port_filter`` `appends the port to an internal dictionary <https://github.com/openstack/neutron/blob/master/neutron/agent/linux/iptables_firewall.py#L60>`_, ``filtered_ports`` which is used to track the internal state.
* Each security group has a `chain <http://www.thegeekstuff.com/2011/01/iptables-fundamentals/>`_ in Iptables.
* The ``IptablesFirewallDriver`` has a method to `convert security group rules into iptables statements <https://github.com/openstack/neutron/blob/master/neutron/agent/linux/iptables_firewall.py#L248>`_