def test_link_add_veth(self): """Test definitiion of veth device. """ netdev.link_add_veth('foo', 'bar') treadmill.subproc.check_call.assert_called_with([ 'ip', 'link', 'add', 'name', 'foo', 'type', 'veth', 'peer', 'name', 'bar' ], )
def on_create_request(self, rsrc_id, rsrc_data): """ :returns ``dict``: Network IP `vip`, network device `veth`, IP gateway `gateway`. """ with lc.LogContext(_LOGGER, rsrc_id, adapter_cls=lc.ContainerAdapter) as log: log.debug('req: %r', rsrc_data) app_unique_name = rsrc_id environment = rsrc_data['environment'] assert environment in _SET_BY_ENVIRONMENT, \ 'Unknown environment: %r' % environment veth0, veth1 = _device_from_rsrc_id(app_unique_name) if app_unique_name not in self._devices: # VIPs allocation (the owner is the resource link) ip = self._vips.alloc(rsrc_id) self._devices[app_unique_name] = {'ip': ip} else: # Re-read what IP we assigned before ip = self._devices[app_unique_name]['ip'] if 'device' not in self._devices[app_unique_name]: # Create the interface pair netdev.link_add_veth(veth0, veth1) # Configure the links netdev.link_set_mtu(veth0, self.ext_mtu) netdev.link_set_mtu(veth1, self.ext_mtu) # Tag the interfaces netdev.link_set_alias(veth0, rsrc_id) netdev.link_set_alias(veth1, rsrc_id) # Add interface to the bridge netdev.bridge_addif(self._TMBR_DEV, veth0) netdev.link_set_up(veth0) # We keep veth1 down until inside the container # Record the new device in our state self._devices[app_unique_name] = _device_info(veth0) self._devices[app_unique_name].update({ 'ip': ip, 'environment': environment, }) # We can now mark ip traffic as belonging to the requested # environment. _add_mark_rule(ip, environment) result = { 'vip': ip, 'veth': veth1, 'gateway': self._TM_IP, 'external_ip': self.ext_ip, } return result
def _bridge_initialize(self): """Reset/initialize the Treadmill node bridge. """ try: # FIXME(boysson): This is for migration when TM_DEV0 used to be a # bridge. netdev.link_set_down(self._TM_DEV0) netdev.bridge_delete(self._TM_DEV0) except subproc.CalledProcessError: pass try: netdev.link_set_down(self._TM_DEV0) netdev.link_del_veth(self._TM_DEV0) except subproc.CalledProcessError: pass try: netdev.link_set_down(self._TMBR_DEV) netdev.bridge_delete(self._TMBR_DEV) except subproc.CalledProcessError: pass netdev.bridge_create(self._TMBR_DEV) netdev.bridge_setfd(self._TMBR_DEV, 0) netdev.link_add_veth(self._TM_DEV0, self._TM_DEV1) netdev.link_set_mtu(self._TM_DEV0, self.ext_mtu) netdev.link_set_mtu(self._TM_DEV1, self.ext_mtu) netdev.bridge_addif(self._TMBR_DEV, self._TM_DEV1) # Force the bridge MAC address to the Treadmill device. This # prevents the bridge's MAC from changing when adding/removing # container interfaces. # (Default Linux bridge behavior is to set the bridge's MAC to be # lowest of it's ports). tm_mac = netdev.dev_mac(self._TM_DEV1) netdev.link_set_addr(self._TMBR_DEV, tm_mac) # Bring up the bridge interface netdev.link_set_up(self._TMBR_DEV) netdev.link_set_up(self._TM_DEV1) netdev.addr_add( addr='{ip}/16'.format(ip=self._TM_IP), devname=self._TM_DEV0 ) # Enable route_localnet so that we can redirect traffic from the # container to the node's loopback address. netdev.dev_conf_route_localnet_set(self._TM_DEV0, True) # Bring up the TM interface netdev.link_set_up(self._TM_DEV0)