Browse Source

basic support for Linux tap devices

our project needs to deploy taps using os-net-config utility. leverage
a dedicated type from ifcfg implementation.

Change-Id: Iaf4294bec6c21f130c7a149d0f45d3be53c1c9cc
changes/16/765816/4
shrike 2 months ago
parent
commit
da7614bc48
8 changed files with 142 additions and 0 deletions
  1. +8
    -0
      etc/os-net-config/samples/linux_tap.json
  2. +6
    -0
      etc/os-net-config/samples/linux_tap.yaml
  3. +11
    -0
      os_net_config/__init__.py
  4. +12
    -0
      os_net_config/impl_ifcfg.py
  5. +36
    -0
      os_net_config/objects.py
  6. +38
    -0
      os_net_config/schema.yaml
  7. +16
    -0
      os_net_config/tests/test_impl_ifcfg.py
  8. +15
    -0
      os_net_config/tests/test_objects.py

+ 8
- 0
etc/os-net-config/samples/linux_tap.json View File

@ -0,0 +1,8 @@
{ "network_config": [
{
"type": "linux_tap",
"name": "tap0",
"use_dhcp": true
}
]
}

+ 6
- 0
etc/os-net-config/samples/linux_tap.yaml View File

@ -0,0 +1,6 @@
network_config:
-
type: linux_tap
name: tap0
use_dhcp: true

+ 11
- 0
os_net_config/__init__.py View File

@ -118,6 +118,8 @@ class NetConfig(object):
self.add_contrail_vrouter(obj)
elif isinstance(obj, objects.ContrailVrouterDpdk):
self.add_contrail_vrouter_dpdk(obj)
elif isinstance(obj, objects.LinuxTap):
self.add_linux_tap(obj)
def add_route_table(self, route_table):
"""Add a route table object to the net config object.
@ -284,6 +286,15 @@ class NetConfig(object):
raise NotImplementedError(
"add_contrail_vrouter_dpdk is not implemented.")
def add_linux_tap(self, linux_tap):
"""Add a LinuxTap object to the net config object.
:param linux_tap:
The LinuxTap object to add.
"""
raise NotImplementedError(
"add_linux_tap is not implemented.")
def apply(self, cleanup=False):
"""Apply the network configuration.


+ 12
- 0
os_net_config/impl_ifcfg.py View File

@ -1114,6 +1114,18 @@ class IfcfgNetConfig(os_net_config.NetConfig):
self._add_rules(contrail_vrouter_dpdk.name,
contrail_vrouter_dpdk.rules)
def add_linux_tap(self, linux_tap):
"""Add a LinuxTap object to the net config object
:param linux_tap:
The LinuxTap object to add
"""
logger.info('adding Linux TAP interface: %s'
% linux_tap.name)
data = self._add_common(linux_tap)
data += "TYPE=Tap\n"
self.interface_data[linux_tap.name] = data
def generate_ivs_config(self, ivs_uplinks, ivs_interfaces):
"""Generate configuration content for ivs."""


+ 36
- 0
os_net_config/objects.py View File

@ -91,6 +91,8 @@ def object_from_json(json):
return SriovPF.from_json(json)
elif obj_type == "sriov_vf":
return SriovVF.from_json(json)
elif obj_type == "linux_tap":
return LinuxTap.from_json(json)
def _get_required_field(json, name, object_name, datatype=None):
@ -1848,3 +1850,37 @@ class ContrailVrouterDpdk(_BaseOpts):
bond_mode=bond_mode,
bond_policy=bond_policy, driver=driver,
cpu_list=cpu_list, vlan_id=vlan_id)
class LinuxTap(_BaseOpts):
"""Base class for Linux tap Interface.
TAP, namely network TAP, simulates a link layer device and operates in
layer 2 carrying Ethernet frames.
A user space program may also pass packets into a TAP device. In this
case the TAP device delivers (or "injects") these packets to the
operating-system network stack thus emulating their reception from an
external source.
"""
def __init__(self, name, use_dhcp=False, use_dhcpv6=False, addresses=None,
routes=None, rules=None, mtu=None, primary=False,
nic_mapping=None, persist_mapping=False, defroute=True,
dhclient_args=None, dns_servers=None, nm_controlled=False,
onboot=True, domain=None, members=None):
super(LinuxTap, self).__init__(name, use_dhcp, use_dhcpv6,
addresses, routes, rules, mtu,
primary, nic_mapping,
persist_mapping, defroute,
dhclient_args, dns_servers,
nm_controlled, onboot, domain)
@staticmethod
def from_json(json):
name = _get_required_field(json, 'name', 'LinuxTap')
(_use_dhcp, _use_dhcpv6, _addresses, _routes, _rules, _mtu, _primary,
nic_mapping, persist_mapping, _defroute, _dhclient_args, _dns_servers,
_nm_controlled, _onboot,
_domain) = opts = _BaseOpts.base_opts_from_json(json)
return LinuxTap(name, *opts)

+ 38
- 0
os_net_config/schema.yaml View File

@ -1077,6 +1077,43 @@ definitions:
- members
additionalProperties: False
linux_tap:
type: object
properties:
type:
enum: ["linux_tap"]
name:
$ref: "#/definitions/string_or_param"
# common options:
use_dhcp:
$ref: "#/definitions/bool_or_param"
use_dhcpv6:
$ref: "#/definitions/bool_or_param"
addresses:
$ref: "#/definitions/list_of_address"
routes:
$ref: "#/definitions/list_of_route"
rules:
$ref: "#/definitions/list_of_rule"
mtu:
$ref: "#/definitions/int_or_param"
nic_mapping:
$ref: "#/definitions/nic_mapping"
persist_mapping:
$ref: "#/definitions/bool_or_param"
defroute:
$ref: "#/definitions/bool_or_param"
dhclient_args:
$ref: "#/definitions/string_or_param"
dns_servers:
$ref: "#/definitions/list_of_ip_address_string_or_param"
nm_controlled:
$ref: "#/definitions/bool_or_param"
required:
- type
- name
additionalProperties: False
linux_bridge:
type: object
properties:
@ -1533,4 +1570,5 @@ items:
- $ref: "#/definitions/vpp_bond"
- $ref: "#/definitions/contrail_vrouter"
- $ref: "#/definitions/contrail_vrouter_dpdk"
- $ref: "#/definitions/linux_tap"
minItems: 1

+ 16
- 0
os_net_config/tests/test_impl_ifcfg.py View File

@ -603,6 +603,15 @@ DRIVER=uio_pci_generic
CPU_LIST=2,3
"""
_LINUX_TAP_IFACE = """# This file is autogenerated by os-net-config
DEVICE=tap0
ONBOOT=yes
HOTPLUG=no
NM_CONTROLLED=no
PEERDNS=no
BOOTPROTO=none
TYPE=Tap
"""
_SRIOV_PF_IFCFG = """# This file is autogenerated by os-net-config
DEVICE=enp3s0f0
ONBOOT=yes
@ -1142,6 +1151,13 @@ class TestIfcfgNetConfig(base.TestCase):
self.provider.interface_data['vhost0'])
self.assertEqual('', self.get_route_config('vhost0'))
def test_add_linux_tap(self):
tap = objects.LinuxTap('tap0', nm_controlled=False)
self.provider.add_linux_tap(tap)
self.assertEqual(
_LINUX_TAP_IFACE,
self.provider.interface_data['tap0'])
def test_add_vlan(self):
vlan = objects.Vlan('em1', 5)
self.provider.add_vlan(vlan)


+ 15
- 0
os_net_config/tests/test_objects.py View File

@ -2443,3 +2443,18 @@ class TestOvsRequiredObjects(base.TestCase):
expected = 'OvsDpdkPort cannot be created as OpenvSwitch is not ' \
'installed.'
self.assertIn(expected, six.text_type(err))
class TestLinuxTap(base.TestCase):
def test_linux_tap_from_json(self):
data = """{
"type": "linux_tap",
"name": "tap0",
"nm_controlled": false
}
"""
linux_tap = objects.object_from_json(json.loads(data))
self.assertEqual("tap0", linux_tap.name)
self.assertEqual(False, linux_tap.nm_controlled)

Loading…
Cancel
Save