Showing posts with label networkmanager. Show all posts
Showing posts with label networkmanager. Show all posts

Wednesday, March 16, 2016

Network namespaces and NetworkManager

This post documents a process to implement support for network namespaces in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 NetworkManager. The code described in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 post can be found on GitHub. While my personal motivation to add namespace support to NetworkManager was to be able to add support for provisioning domains as specified by IETF MIF WG, it also brings benefits to existing users by allowing isolation of different applications into different network namespaces. The best example is a VPN connection isolation. When network namespaces are used cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n certain applications can be started in namespace in which only network connectivity is via VPN. Those applications can access VPN resources while all cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r applications, that are in different network namespaces, will not see VPN connection and thus couldn't use cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365m. The additional benefit would be from using multiple connections, as described by MIF Architecture RFC.

Note that after I started to work on this, Thomas Haller implemented basic support for namespaces in NetworkManager that was a bit different in some implementation details from mine.

The idea


The intention of implementing support for network namespaces was to allow applications to be isolated so that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365y use specific network connections. Network namespaces in Linux kernel have some properties that anyone that wants to use cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365m must be aware of. This is documented in a separate post.

So, an application can not be moved between different network namespace by some ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r application, i.e. only application itself can change network namespaces, and only if it has appropriate permissions.

So, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 idea is cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 following one. Application is started in some network namespace. This can be done easily (e.g. see 'ip netns exec' command). Then, this network namespace is manipulated by eicá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 application itself - it is aware of NM's support for network namespaces, or by third party application (that application could be nmcli). The manipulation means that requests are sent to NetworkManager via D-Bus to make changes to network namespace. The changes can be activation and deactivation of certain connections. NetworkManager, based on those requests and on specifics of connections and devices those connections are bound to, determines what to do. For example, it can create virtual device in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 network namespace, or can move physical device. Basically, this part isn't important to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 application itself, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 only thing that is important is that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 application is assigned requested connections.

Implementation


The following changes were made to NetworkManager in order to introduce support for network namespaces:

  1. Created new object NMNetnsController whose purpose is to allow management of all network namespaces controlled by NetworkManager. Via cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 interface org.freedesktop.NetworkManager.NetworkNamespacesController it is possible to create a new network namespace, or to remove cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 existing one. It is also possible to obtain a list of existing network namespaces.
     
  2. Created new object NMNetns that represents a single network namespace. So, when new network namespace is created a new object NMNetns is created and exposed on D-Bus. This object allows manipulation with network namespace via cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 interface org.freedesktop.NetworkManager.NetNsInstance. So, it is possible to get a list of all devices within cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 network namespace, take certain device from some ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r network namespace and to activate some connection.
     
  3. NMSettings is now singleton object. This wasn't so significant change because cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re was also one object of this type before, but now it is more explicitly exposed as such.
     
  4. NMPlatform, NMDefaultRouteManager and NMRouteManager aren't singleton objects any more. They are now instantiated for each new network namespace that is created.


VPN isolation


VPN isolation was done as a first user of network namespaces implementation. It was easier cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r connections because cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 assumption was that VPN connection should live only in single network namespace and it should be cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 only available connection.

At cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 beginning, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re was doubt on where to place cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 knowledge of network namespace and two places were candidates, in NMActiveConnection and NMVPNConnection classes. NMActiveConnection is actually a base class of NMVPNConnection class. The modification of NMVPNConnection approach is better for cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 following reason because cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 idea was to introduce new configuration parameter in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 configuration file of a VPN connection that will specify that isolation is necessary and also some additional behaviors:
  • netns-isolate

    Boolean parameter (yes/no) which defines weacá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r VPN connection should be isolated within a network namespace or not. For backwards compatibility reasons
     
  • netns-persistent

    Should network namespace be persistant (yes) or not (no). Persistant namespace will be retained when VPN connection is terminated, while non-persistant will be removed.
     
  • netns-name

    Network namespace name. Special value is uuid which means connection's UUID should be used, also name is special value that requests connection's name to be used. Finally, any ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r string is taken as-is and used as a network namespace name.
     
  • netns-timeout

    How much time to wait (in milliseconds) for device to appear in target namespace.
Basically, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 implementation is such that when device appears in root network namespace it is taken from cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re (using TakeDevice method, but called directly instead via D-Bus).  When device appears in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 target network namespace network parameters are assigned to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 interface. This was tested with OpenVPN type of VPN.

The implementation has two problems. First, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 case of VPN connections that don't create virtual devices but instead just modify packet processing rules in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Linux kernel (i.e. XFRM). Secondly, hostname and name resolution parameters aren't assigned because cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 infrastructure is lacking in that respect.

Conclusion


The initial goal of having network namespaces support in NetworkManager was achieved. There are functionalities missing like isolation of any connection, hostname handling and DNS resolution handling. Those are things that will have to be resolved in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 future.

NetworkManager and multiple provisioning domains

The goal of this post is to list different options on how to introduce PvDs into cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 NetworkManager, i.e. what should be changed in NetworkManager and how it should handle explicit and implicit PvDs. But first we'll start with cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 definition of Provisioning Domain and object that could potentially be used to store/represent Provisioning Domains. The implementation this post refers to can be found on GitHub.

The term Provisioning Domain (PvD) is defined and clarified in RFC7556 as:
A consistent set of network configuration information. Classically, all of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 configuration information available on a single interface is provided by a single source (such as a network administrator) and can cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365refore be treated as a single provisioning domain.  In modern IPv6 networks, multihoming can result in more than one provisioning domain being present on a single link.  In some scenarios, it is also possible for elements of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 same PvD to be present on multiple links.
Basically it is a set of configuration information that should be treated as a single unit. Here are some examples of such units of configuration data:
  1. Static IPv4 configuration provided by a user for a server or for a network without DHCP.
  2. Data handed over to a client by DHCP server.
  3. On an IPv6 enabled local network with a single router which sends configuration data in RA to nodes attached to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 network.
  4. Configuration data sent by VPN gateway upon successful connection of a client. 
In all cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365se cases we have implicit PvDs, meaning that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 sets of configuration data are implicitly bound togecá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re was no indication whatsoever that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365y should be treated as a single unit. This is in contrast to explicit PvDs which are sets of configuration data bound togecá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r by some explicit mechanism and associated with some kind of a PvD identifier sent to a client in some way. Explicit PvDs, as of time this post was written, don't exist yet, and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 IETF MIF working group is trying to define necessary mechanisms to support cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365m as well as how exactly IDs should look like.

Note that apart from explicit PvD and implicit Pvd we also differentiate between PvD and PvD instance. The difference is that PvD consists of a set of PvD instances thate are cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 same on some local network, while PvD instance is valid for only a single host on a given local network. In ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r words, PvD will include network prefix and mask, while PvD instance will include host addresses too. It is interesting to note that router advertisements communicate PvDs while DHCP communicates PvD instaces.

How to implement PvDs in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 NetworkManager

As always, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 same goal can be achieved in multiple ways, so here are cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 options on how PvDs can be implemented within NM. Basically, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re are two main approaches: first, existing objects can be enhanced so that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365y can represent PvDs or a completely new object can be introduced.

Using NMSettingsConnection object to store PvD and PvD instance


Each network connection (which is not cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 same as PvD or PvD instance) is stored in NMSettingsConnection object. Those objects are generated from static files or dynamically during NetworkManager's execution. NMSettingsConnection objects are initialized from cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 following sources:
  1. Distribution configuration files. System dependent network configuration files (e.g. /etc/sysconfig/network-scripts for RHEL based systems) are read by NM via plugins and NMSettingsConnection objects are created as a result.
     
  2. Network manager specific configuration. NetworkManager has its own configuration files that are stored in /etc/NetworkManager/system-connections/.
  3. Dynamically created configurations. While running, NetworkManager allows new configurations to be created via D-Bus interface.
Note that NetworkManager has a concept of profiles that are used in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 case of Wired networks. Basically, those are settings which are not bound to any specific network interface. Profiles can have 802.1x type of credentials assigned to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365m.

So, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 idea of integrating PvDs into NetworkManager is for each new PvD or PvD instance to create a new NMSettingsConnection object. The modification to NMSettingsConnection should be extended with PvD ID parameter.

There are several potential problems with this approach:
  1. There is a difference between NMSettingsConnection on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 one hand, and PvD and PvD instance on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r hand. For example, some NMSettingsConnection defines a network connection that should be configured using DHCP and in that case cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 NMSettingsConnection isn't PvD nor PvD instance. On cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r hand, NMSettingsConnection can be cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 same as PvD instance. This is cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 case with static IPv4 configurations when a user specifies concrete IP addresses. Finally, NMSettingsConnection can be PvD only in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 case of IPv6 when host part is generated from MAC address.
  2. When PvDs and PvD instances are received cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365y are valid only for cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 interface on which cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365y are received. But, a user can request any NMSettingsConnection object to be activated on any interface which isn't possible.
  3. Also, this can create confusion. Take for example preconfigured NMSettingsConnection which is now treated as PvD with a specific PvD ID, and it is defined to use DHCP for cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 configuration. Obviously, this PvD ID is expected to be valid on a certain interface on a specific attachment point. But due to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 way cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 interface is configured (DHCP) it can actually be activated on any interface on any network that supports DHCP. Thus, it might easily happen that a user by mistake activated this particular NMSettingsConnection on a "wrong" network and so makes a user believe cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 network is active while in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 reality it is not.

    Note that even NMSettingsConnection objects that contain credential information aren't guaranteed to retrieve cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 same PvD every time cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 connection is made. Namely, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re are AAA servers and infrastructure that allow clients with a same credentials to connect to multiple networks, and thus to potentially receive multiple PvDs.
     
  4. Finally, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 problem is that on a single network interface only one NMSettingsObject might be activated and so this prevents having multiple PvDs on a single interface.
Those problems are not unsolvable, i.e. cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365y could be solved by modifying certain aspects of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 NetworkManager in general, and NMSettingsObject in particular.

Treating NMActiveConnection object as PvD instance and PvD


Whenever a connection is made in NetworkManager an object is created. Basically, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re are two classes for cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 object, both of which inherit from NMActiveConnection base class. Which class is used depends on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 type of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 connection. Basically,  cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 only distinction is made between VPN connections that are represented by NMVPNConnection objects and ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r connections that are represented by NMActRequest objects. The main task of NMActiveConnection is to bind NMSettingsConnection with NMDevice objects.

The idea in this case is to treat NMActiveConnection as a PvD or a PvD instance, i.e. on each new PvD or PvD instance received new NMActiveConnection is created.

But, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re are still some problems:
  1. Since NMActiveConnection objects are transient that means that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re would be no history of PvDs used. This might, or might not be a problem, depending on whecá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r we need this history or not.

    The cases when cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 history would be necessary is if we cache some information for cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 next time we connect to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 given PvD. The second case is if cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re are processes still using PvD through API and thus cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 information about PvD must live until cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 process dies. Note that this letter problem could be solved with delayed removal of NMActiveConnections or by some asynchronous mechanism informing applications that specific NMActiveConnection isn't available any more.
     
  2. The second problem is cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 question if cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re could exist two ActiveConnection objects that were created from cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 same NMSettingsConnection object, i.e. can NMSettingsConnections be shared.
     
  3. The third problem is that it will happen from within a single NMActiveConnection that two or more PvDs are received and this requires that NMActiveConnection is a factory for itself.

Using NMIP4Config and NMIP6Config objects for PvDs and PvD instances


NetworkManager has object/classes for storing IPv4 (libnm-core/nm-setting-ip4-config.c) and IPv6 (libnm-core/nm-setting-ip6-config.c) settings. More precisely, those objects are used to expose network settings of devices to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 rest of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 NetworkManager. So, in some way cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365y are PvDs in a sense that each of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365m contains enough information to allow connection to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 network.

The problem is that internally NetworkManager keeps a single IPv4/IPv6 configuration object per device and in addition it merges all received configuration data on a single interface.

Specifically, in case of configuration data received in RAs everything is kept in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 object NMRdisc defined in src/rdisc/nm-rdisc.h. There you'll find arrays of received configuration data. NetworkManager assumes that a single router sends all cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 configuration data. This assumption is not valid on a multihomed network, or a network that can send multiple provisioning domains within each RA. What would be necessary is to change this structure so that configuration data is kept separate for each router and provisioning domain.

The problems in this case are:
  1. NMIPxConfig objects were not intended to keep information about available IPv4 and IPv6 addresses but to make available addresses configured on device. So, it reverses cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 purpose of those objects which isn't accepted so well.
  2. Again, those are transient objects and thus cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re is no history. It is possible to keep every object alive, but NM isn't designed to behave in such way.
  3. It seems that in libnm cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re is no way to obtain a list of IPv4 and IPv6 objects.

Having separate PvD structures


This is cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 final alternative and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 most intrusive one. The idea is that settings, active connections and IPv6 and IPv6 objects/classes stay as is, but instead, when each new connection is established a new PvD data structure is created. PvD is inferred from configuration settings or cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 NetworkManager received explicit PvD.

This would solve cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 problem that some settings might be used to obtain different PvDs which isn't known until connection is established. For example, if we are using DHCP to configure cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 interface, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n, PvD received depends on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 PoA.

It would also solve cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 problem that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 user might try to instantiate one PvD, while some ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r is actually in use. This way, after cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 connection is established, appropriate PvD is searched for, or new one is created.

This is most intrusive change that would require change in APIs and thus break compatibility with cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 existing applications (or require a completely new API).

Current PvD Support Implementation


The first implementation of PvDs was done using NMIP6Config as a PvD container. Before describing cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 implementation we have to state that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 only mechanism currently able to carry PvDs is RA messages. NMIP6Config objects are extended with PvD ID field. At first, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re was support for different types of PvD IDs and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 first implemented type was UUID stored in ASCII format. Later in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 development process PvD ID types were removed and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 only possible type is UUID. It seems that this doesn't make implementations less flexible and in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 same time substantially reduces complexity.

When RA is received, and after it is processed as usual, a new implicit PvD is created from data in RA. If cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re are two or more routers on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 local network, each sending its own configuration data, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n a separate PvD is created for each RA. Also, in case cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re are PVD container option in RA it is parsed and additional PvD is created from that data.

This information is cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n handled to NMDevice object which merges data from implicit PvDs (as it does in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 unmodified version) but now cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re is also a hash table with set of PvDs received on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 given interface. This information is cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n exposed through NMActiveConnection object.



Friday, February 12, 2016

Few notes about network namespaces in Linux

For some time I'm working with network namespaces as implemented in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Linux kernel. Here I'll collect some notes about cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 implementation, behavior, usage and anything else I learn while using network namespaces.

Kernel API for NETNS


Kernel offers two system calls that allow management of network namespaces. The first one is for creating a new network namespace, unshare(2). Actually, this system call allows ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r types of namespaces to be created, but here we are interested only in network namespaces. So, to create a new network namespace you should call cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 function like this:
#include
...
    unshare(CLONE_NEWNET);
...
And that would define a new network namespace.

There are two ways ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r processes can now use that network namespace. The first approach is for cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 process that created new network namespace to fork ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r processes and each forked process would share and inherit cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 parent's process network namespace. The same is true if exec is used.

The second system call kernel offers is setns(2). To use this system call you have to have a file descriptor that is somehow related to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 network namespace you want to use. There are two approaches how to obtain cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 file descriptor.

The first approach is to know cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 process that lives currently in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 required network namespace. Let's say that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 PID of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 given process is $PID. So, to obtain file descriptor you should open cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 file /proc/$PID/ns/net file and that's it, pass file descriptor to setns(2) system call to switch network namespace. This approach always works.

The second approach works only for iproute2 compatible tools. Namely, ip command when creating new network namespace creates a file in /var/run/netns directory and bind mounts new network namespace to this file. So, if you know a name of network namespace you want to access (let's say cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 name is NAME), to obtain file descriptor you just need to open(2) related file, i.e. /var/run/netns/NAME.

Note that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re is no system call that would allow you to remove some existing network namespace. Each network namespace exists as long as cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re is at least one process that uses it, or cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re is a mount point.

Two remarks for cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 end of this section. First, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re is no system call that would allow one process to move some ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r process into anocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r network namespace! And second, you need appropriate privileges to use cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 mentioned system calls, i.e. regular user processes can't switch namespaces.

Socket API behavior


The next question is how Socket API behaves when network namespaces are used, and things here are quite interesting.

First, each socket handle you create is bound to whatever network namespace was active at cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 time cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 socket was created. That means that you can set one network namespace to be active (say NS1) create socket and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n immediately set anocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r network namespace to be active (NS2). The socket created is bound to NS1 no matter which network namespace is active and socket can be used normally. In ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r words, when doing some operation with cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 socket (let's say bind, connect, anything) you don't need to activate socket's own network namespace before that!

Also, to note is that network namespace is per-thread setting, meaning if you set certain network namespace in one thread, this won't have any impact on ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r threads in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 process.

Command line tools


There are two command line tools available to manipulate network namespaces. The first one is nsenter(1) which isn't specific to networking. It allows one to start some process within predefined network namespace. The second tool is ip command from iproute2 package. It allows management of network namespaces and also allows network interfaces to be switched between different namespaces.

NETLINK behavior

To change device from one network namespace to anocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r one, NETLINK must be used. I found somewhere references to /sys files, but at least on my system cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365y don't appear to exist.

One interesting fact is that interface ID is global across all network namespaces - except for loopback interface, i.e. if you create interface in one network namespace and it gets ID N, and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n you move it to anocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r network namespace, it will keep ID N.

TBD.

Tuesday, February 2, 2016

NetworkManager architecture

After figuring out how VPN establishment works in NetworkManager cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 next big question is about cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 architecture of NetworkManager and its run-time behavior. This post tries to provide answer to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 given question. This post consists of two parts. The first part, Source code organization, gives information about cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 source tree organization of NetworkManager. The second part, Run-time initialization behavior has a goal to describe initialization of NetworkManager and its key parts. Note that I'll update this post as I learn about NetworkManager.

The last update time of this post was: February 2nd, 2016.

Source code organization

So, let us start with a source tree organization. If you take a look at cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 top level directory of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 NetworkManager git tree, you'll find cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re some files and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 set of directories. The files are build scripts and configuration files, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re are also some documentation files. But, in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 end all cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 interesting functionality is placed within cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 top level directories. There are cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 following top level directories:
  • callouts

    TBD
     
  • clients

    Clients to control NM like nmcli or nmtui.
     
  • introspection

    contains XML description of DBus interfaces provided by NetworkManager and its components. For example, VPN plugins are external to NetworkManager but cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365y use DBus to communicate with NetworkManager and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re is an XML file that describes VPN plugin's interfaces. All cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 descriptions are converted into C code stubs and skeletons using dbus-binding-tool. There is a lot of magic staff happening here.
     
  • libnm

    Libraries intended to be used by clients accessing and using services provided by NetworkManager. This also includes application that control NetworkManager itself (like nmcli and nmtui)
     
  • libnm-core

    Core NM libraries used by NetworkManager itself and all cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r components, like command line utilities.
     
  • libnm-gliblibnm-util

    Old NM libraries that are deprecated starting with 1.0 release of NetworkManager. Still, it seems that at least some functionality is used from those libraries so probably until all cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 pieces of NetworkManager are converted to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 new libraries cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365y are to stay. Note that in my posts I ignore cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 content of those libraries as much as possible and I concentrate on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 previous two libraries, libnm and libnm-core.
     
  • src

    The directory with cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 code specific to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 NetworkManager unlike cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 previous directories that contain code used by different programs. The src/ directory contains file and  a number of subdirectories:
     
    • devices/

      Classes and sub classes used to represent different networking devices, real and virtual, that can be managed by NetworkManager.
       
    • dhcp-manager/

      Manager class that manages and interfaces DHCP clients to NetworkManager.
       
    • dns-manager/


       
    • dnsmasq-manager/


       
    • platform/

      Platform specific code that interfaces NetworkManager to particular operating system it is running on. For cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 moment cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re is a base class and derived Linux specific class.
       
    • ppp-manager/


       
    • rdisc/

      Code to monitor and parse IPv6 router advertisement messages.
       
    • settings/

      Code to keep track of connections. Since connections are read from configuration files that depend on particular distributions this directory also contains plugins, one plugin for each supported distribution.
       
    • supplicant-manager/


       
    • systemd/


       
    • vpn-manager/

      VPN specific code. Here is a manager class that is used to manage all cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 VPN connections and also class that is used to represent each active VPN connection.
       


Run-time initialization behavior


When NM is started execution starts from main() function that can be found in src/main.c. The goal of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 main function is to parse command line options, check some prerequisites for running NM, do initialization steps and start glib main loop. The most interesting are initialization steps which are:
  • Initialize logging.
     
  • Create configuration object singleton, NM_TYPE_CONFIG (defined in file src/nm-config.c).
     
  • Creates a singleton for managing DBus connections and communication, NM_TYPE_BUS_MANAGER (defined in file src/nm-bus-manager.c).
     
  • Creates a singleton that is platform dependent used for management of network subsystem, NM_TYPE_LINUX_PLATFORM (defined in file src/platform/nm-linux-platform.c).
     
  • Creates a main singleton object of class NM_TYPE_MANAGER (defined in file src/nm-manager.c).
     
  • Initializes loopback interface.
So, while NetworkManager is running it basically consists of a set of singleton objects that communicate and make what is named NetworkManager.

References




Wednesday, January 13, 2016

Connections in NetworkManager

Connections, as defined and used by NM, are very close to PvDs. The goal of this post is to analyse data structures/functions for connections within NetworkManager and so that plan of integrating PvDs into NM can be developed. This is done in a separate post.

A definition of connection in NetworkManager can be found in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 comment within cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 libnm-core/nm-connection.c file:
An #NMConnection describes all cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 settings and configuration values that are necessary to configure network devices for operation on a specific network. Connections are cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 fundamental operating object for NetworkManager; no device is connected without a #NMConnection, or disconnected without having been connected with a #NMConnection.

Each #NMConnection contains a list of #NMSetting objects usually referenced by name (using nm_connection_get_setting_by_name()) or by type (with nm_connection_get_setting()). The settings describe cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 actual parameters with which cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 network devices are configured, including device-specific parameters (MTU, SSID, APN, channel, rate, etc) and IP-level parameters (addresses, routes, addressing methods, etc).
In cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 following text we'll see how connections are implemented in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 NM code, how cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365y are initialized and how cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365y are accessed over cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 DBus. Note that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re are some parts related to connections that are specific for a system/distribution on which NM is running. In that case I concentrate on how things are done on Fedora (and very likely all RHEL derivatives).

Class and interface hierarchy


The base for all connection objects in NetworkManager is cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 interface defined in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 files libnm-core/nm-connection.[ch]. The interface is implemented by cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 following classes:
  • Class NMSettingsConnectionClass defined in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 files  src/settings/nm-settings-connection.[ch].

    This class is used by NetworkManager daemon and it is exported via DBus interface.
     
  • Class NMRemoteConnectionClass defined in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 files libnm/nm-remote-connection.[ch].

    Used by clients in clients subdirectory.
     
  • Class NMSimpleConnectionClass defined in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 files libnm-core/nm-simple-connection.[ch].

    This is cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 object passed via DBus so it is for communicating connections from and to NetworkManager and its clients.

Accessing individual connection data stored in NetworkManager


Each connection, active or not, known to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 NetworkManager is exposed through DBus on path /org/freedesktop/NetworkManager/Settings/%u where %u is a sequence number assigned to each connection. Interface implemented by each connection is org.freedesktop.NetworkManager.Settings.Connection. The interface is described in introspection/nm-settings-connection.xml file.

To invoke a method defined in interface on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 given object you can use dbus-send command line tool like this:
dbus-send --print-reply --system \
    --dest=org.freedesktop.NetworkManager \
    /org/freedesktop/NetworkManager/Settings/0 \
    org.freedesktop.NetworkManager.Settings.Connection.GetSettings
In this particular case we are invoking GetSettings method on object /org/freedesktop/NetworkManager/Settings/0 which will return us its configuration parameters. Note that invoking this particular method is easy since cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re are no arguments to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 method.

The class that represents connection, and that is answering to DBus messages, is declared in src/settings/nm-settings-connection.[ch] files. This class implements interface NM_TYPE_CONNECTION and also subclasses NM_TYPE_EXPORTED_OBJECT class.  The NM_TYPE_EXPORTED_OBJECT class has all cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 methods necessary to expose cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 object on DBus.

To see what functions are called when DBus methods are called take a look at cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 end of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 source file nm-settings-connection.c. There, you'll find cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 following code:
nm_exported_object_class_add_interface (NM_EXPORTED_OBJECT_CLASS (class),
    NMDBUS_TYPE_SETTINGS_CONNECTION_SKELETON,
    "Update", impl_settings_connection_update,
    "UpdateUnsaved", impl_settings_connection_update_unsaved,
    "Delete", impl_settings_connection_delete,
    "GetSettings", impl_settings_connection_get_settings,
    "GetSecrets", impl_settings_connection_get_secrets,
    "ClearSecrets", impl_settings_connection_clear_secrets,
    "Save", impl_settings_connection_save,
    NULL);
What this code does is that it binds GBus methods to function that should be called. When we called GetSettings method, obviously that ended up in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 function impl_settings_get_settings().

The first step done when processing GetSettings method is authorization check. After authorization check has succeeded, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 return message is constructed in get_settings_auth_cb() method.


Accessing and manipulating all connections in NetworkManager


NetworkManager exposes interface org.freedesktop.NetworkManager.Setting on object org.freedesktop.NetworkManager.Setting that, among ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r things, allows cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 user to retrieve list of all cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 known connections to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 NetworkManager.  To get all connections you would could use cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 following dbus-send command:
dbus-send --print-reply --type=method_call --system \
        --dest=org.freedesktop.NetworkManager \
        /org/freedesktop/NetworkManager/Settings \
        org.freedesktop.DBus.Properties.Get \
        string:org.freedesktop.NetworkManager.Settings \
        string:"Connections"
This would get you something like cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 following output:
variant array [
   object path "/org/freedesktop/NetworkManager/Settings/10"
   object path "/org/freedesktop/NetworkManager/Settings/11"
   object path "/org/freedesktop/NetworkManager/Settings/12"
   object path "/org/freedesktop/NetworkManager/Settings/13"
   object path "/org/freedesktop/NetworkManager/Settings/14"
   object path "/org/freedesktop/NetworkManager/Settings/15"
   object path "/org/freedesktop/NetworkManager/Settings/0"
   object path "/org/freedesktop/NetworkManager/Settings/1"
   object path "/org/freedesktop/NetworkManager/Settings/2"
   object path "/org/freedesktop/NetworkManager/Settings/3"
   object path "/org/freedesktop/NetworkManager/Settings/4"
   object path "/org/freedesktop/NetworkManager/Settings/5"
   object path "/org/freedesktop/NetworkManager/Settings/6"
   object path "/org/freedesktop/NetworkManager/Settings/7"
   object path "/org/freedesktop/NetworkManager/Settings/8"
   object path "/org/freedesktop/NetworkManager/Settings/9"
   object path "/org/freedesktop/NetworkManager/Settings/16"
]
The exact output will depend on your particular setup and usage.

The given interface and property is implemented by class NMSettingsClass (defined in src/settings/nm-settings.[ch]). This class implements interface NM_TYPE_CONNECTION_PROVIDED (defined in src/nm-connection-provider.[ch]). There is only one object of this class in NetworkManager and it is instantiated when NetworkManager is starting.

Looking in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 file src/settings/nm-settings.c you can see at cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 end registration of function to be called when DBus messages are received. DBus interface of this module is defined in introspection/nm-settings.xml file. Here is cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 relevant code that binds DBus methos to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 functions that implement cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365m:
nm_exported_object_class_add_interface (
        NM_EXPORTED_OBJECT_CLASS (class),
        NMDBUS_TYPE_SETTINGS_SKELETON,
        "ListConnections", impl_settings_list_connections,
        "GetConnectionByUuid", impl_settings_get_connection_by_uuid,
        "AddConnection", impl_settings_add_connection,
        "AddConnectionUnsaved", impl_settings_add_connection_unsaved,
        "LoadConnections", impl_settings_load_connections,
        "ReloadConnections", impl_settings_reload_connections,
        "SaveHostname", impl_settings_save_hostname,
        NULL);
So, when we called ListConnections method, obviously that ended up in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 function impl_settings_list_connections(). Here, we'll emphasize one more method, LoadConnections. This DBus method, implemented in impl_settings_load_connections(), load all connections defined in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 system. We'll take a look now at that method.

Initializing connections


All network connections are loaded and initialized from two sources: system dependent network configuration and VPN configuration scripts.

System dependent network configuration


There are several types of distributions with different network configuration mechanisms. Since that part is obviously system dependent, NetworkManager has a plugin system that isolates cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 majority of NetworkManager code from those system dependent parts. Plugins can be found in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 directory src/settings/plugins. Additionally, all cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 plugins are based on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 src/settings/plugin.[ch] base class. In cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 case of Fedora Linux (as well as RHEL, CentOS and ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r derivatives) network configuration is recorded in scripts in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 directory /etc/sysconfig/network-scripts. and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 plugin that handles those configuration files is stored in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 directory src/settings/plugins/ifcfg-rh.

The initialization of connections stored in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 directory /etc/sysconfig/network-scripts is done when NetworkManager bootstraps and instantiates object NMSettings of type NMSettingsClass. This is performed in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 function nm_manager_start() in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 file src/nm-manager.c. There, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 method nm_settings_start() is called on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 NMSettings object which in turn first initializes all plugins (as, by default, found in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 directory /usr/lib64/NetworkManager/). It cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n calls private method load_connections() to actually load all connections. Note that in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 directory  /usr/lib64/NetworkManager/ cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re are plugins of ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r types too, but only plugins that have prefix libnm-settings-plugin- are loaded. Which plugins should be loaded are can be defined in three places (lowest to highest priority):

  1. Compile time defaults, as given to configure.sh script, or, by default for RHEL type systems "ifcfg-rh,ibft" plugins.
  2. In configuration file /etc/NetworkManager/NetworkManager.conf.
  3. As specified in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 command line.

Method load_connections() iterates over every defined plugin and asks each plugin for all registered connections it knows by calling a method get_connections() within a specific plugin. For RedHat type of distributions cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 plugin that handles all connections is src/nm-settings/plugins/ifcfg-rh/plugin.c and in that file function get_connections() is called. Now, if called for cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 first time, this function will in turn call read_connections() within cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 same plugin/file that will read all available connections. Basically, it opens directory /etc/sysconfig/network-scripts and builds a list of all files in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 directory. Than, it tries to open each file and only those that were parsed properly are left as valid connections. Each found connection is stored in object NMIfcfgConnection of type NMIfcfgConnectionClass. These objects are defined in files src/nm-settings/plugins/ifcfg-rh/nm-ifcfg-connection.[ch].

When all cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 connections were loaded, read_connections() returns a list of all known connections to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 plugin. The function load_connections() cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n, for each connection reported by each plugin, calls claim_connection() method in nm-connection.c. This function, among ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r tasks, exports cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 connection via DBus in a form described above, in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 section Accessing individual connection data stored in NetworkManager.

VPN configuration scripts


Details about VPN connections are stored in /etc/NetworkManager/system-connections directory, one subdirectory per VPN. Those files are read by src/vpn-manager/nm-vpn-manager.c when cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 object is initialized and as such initialized when VPN manager is initialized. VPN manager also also monitors changes in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 VPN configuration directory and acts appropriately.

Properties of a connection


Each connection has a set of properties attached to it in a form of a key-value pairs.

Activating a connection


A connection is activated by calling ActivateConnection DBus method. This method is implemented in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 NetworkManager's main class/object, NMManager. This class/object is a singleton object who's impementation is in src/nm-manager.[ch] files. Looking at cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 code that binds DBus methods to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 functions that implement cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365m we can see that ActivateConnection is implemented by cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 function impl_manager_activate_connection(). The ActivateConnection method, and its implementation function, accept several parameters:
  1. Connection that should be activated identified by its connection path (e.g. "/org/freedesktop/NetworkManager/Settings/2").
  2. Device on which connection should be activated identified by its path (e.g. "/org/freedesktop/NetworkManager/Devices/2").
  3. Specific object?
Some of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 input argument can be unspecified. To make cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365m unspecified in DBus call cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365y should be set to "/" and this will be translated into NULL pointer in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 impl_manager_activate_connection() function. Of all combinations of parameters (with respect to being NULL or non-NULL) cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 following ones are allowed:
  1. When connection path is not specified device must be given. In that case all cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 connections for that device will be retrieved and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 best one will be selected. "The best one" is defined as cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 most recently used one.
  2. If connection path is specified, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n device might or might not be specified. In case it is not defined cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 best device for cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 given connection will be selected. To determine "cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 best device" first list of all devices is retrieved and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n for each device status is checked (must be managed, available, compatible with cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 requested connection). Note that "compatible with cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 requested connection" means, for example, you can not start wireless connection on a wired connection.
There are "software only", or virtual, connections. Those are checked in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 function nm_connection_is_virtual() which is implemented in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 file libnm-core/nm-connection.c. When this post was written, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 following connections were defined as virtual, or software only:
  • Bond
  • Team
  • Bridge
  • VLAN
  • TUN
  • IPtunnel
  • MACVLAN
  • VXLAN
Finally, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re are also VPN connections that also don't have associated devices.

When all cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 checks are performed, devices and connections are found, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n an object of type NMActiveConnection is created in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 function _new_active_connection(). Here, in case VPN connection is started, VPN establishment is initiated and you can read more about that process in anocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r post.


Sunday, January 3, 2016

Few tips about GObject for C++ programmers

While studying NetworkManager code I got more and more comfortable with OO programming retrofitted into C programming language using GObject library. At first I was confused because it is quite complex and I didn't well understand how it works. Furcá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365rmore, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 documentation for beginners is lacking and scare. But, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 more I learned cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 more logical it seemed to me. Since I'm well acquainted with C programming language and to some extent to C++ I decided to write about OO model in GObject, NetworkManager and C based on what someone might expect from C++. As usual, this is for my later reference, but also for everyone else wanting to learn how to use or understand GObject. I'll write in a form of tips, or details you should know in order to better understand how it works.

Declaring a class


In C++ language cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re are two parts of class implementation. First, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re is a class declaration and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re is a class definition. Class declaration goes into a header file (e.g. Point.h) and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re you'll find something like this:
class Point {
}
Now, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 question is how to do this in C using GObject? The process is a bit more involved due to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 characteristics of a C programming language. Anyway, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 recipe is cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 following one. In cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 header file (e.g. point.h) that declares class method you would put cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 following code:
#include

#define TYPE_POINT (point_get_type())

typedef struct _PointClass {
    GObjectClass parent_class;
} PointClass;

typedef struct _Point {
    GObject parent_instance;
} Point;

GType point_get_type(void);
This code declares two structures, one that will be used by a class (PointClass) and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 anocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r one for each object of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 given class type (Point). You would also need to define class and object initialization functions as follows:
#include "point.h"

typedef struct _PointPrivate PointPrivate;

G_DEFINE_TYPE (Point, point, G_TYPE_OBJECT);

static void point_class_init (PointClass* klass)
{
}

static void point_init (Point* self)
{
}
Finally, you can write a main function (in e.g. main.c file) which doesn't do anything, but, nevercá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365less cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 class is here. That's how you would declare a class.

The code for this example can be found on GitHub.

Final and derivable classes


The distinction between cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 two is that you can not subclass final class, while on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r hand, derivable classes can be sub classed. I don't want to go into discussions why final classes, but only into technical details related to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365ir use in GObject. GObject documentation recommends to use final classes if you can, and only cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n derivable classes. If you take a look at some ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r sources, especially for C++, you'll find doubts about benefits of final classes.

So, in C++ (at least from C++11) you would declare final class like this:
class Point final {
};
Now, if you try to subclass it:
class Point2 : public Point {
};
You'll receive compiler error due to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 final keyword prohibiting class Point to be subclassed:
g++ -Wall -std=c++11 main.cpp -o main
In file included from main.cpp:1:0:
Point.h:6:7: error: cannot derive from ‘final’ base ‘Point’ in derived type ‘Point2’
 class Point2 : public Point {
       ^
Note that nothing special has to be done in order for a class to be derivable. Only if you want a class to be final you have to explicitly say so. So, what about GObject and final and derivable classes?

Two macros are used in GObject to create classes for cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 purpose of creating final and derivable classes. To define final class use G_DECLARE_FINAL_TYPE macro. You should modify header file from cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 previous example like this:
#include

#define TYPE_POINT (point_get_type())
G_DECLARE_FINAL_TYPE(Point, point, , POINT, GObject)

typedef struct _Point {
    GObject parent_instance;
} Point;
Note that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re is no definition of type PointClass! The reason is that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 macro G_DECLARE_FINAL_TYPE declares it. Also, point_get_type() isn't declared because G_DECLARE_FINAL_TYPE declares it. That's basically it for final class.

To declare derivable class, macro G_DECLARE_DERIVABLE_TYPE is used. In this case, as in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 previous, you should only change header file which should look like this:
#include

#define TYPE_POINT (point_get_type())
G_DECLARE_DERIVABLE_TYPE(Point, point, , POINT, GObject)

typedef struct _PointClass {
    GObjectClass parent_instance;
} PointClass;
This time, PointClass type is defined explicitly while Point is defined by G_DECLARE_DERIVABLE_TYPE macro.

The code for this example can be found on GitHub.

Instantiate cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 object of a given class


The next thing is how would you instantiate an object of some class. For sample, to instantiate an object of a class written in C++ from cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 previous section in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 main function you would do cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 following:
Point* point = new Point();
To do cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 same thing in C/GObject combo, you again have to do a bit more work. Actually, you have to define allocator for a class, i.e. something equivalent to a new keyword in C++. The way to create a new object of a given type is:
Point *point = someclass_new();
So, you need to define cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 function someclass_new(). Our will be very simple one:
Point* point_new(void)
{
        return g_object_new(TYPE_POINT, NULL);
}
Place it at cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 end of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 file point.c and in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 main function create an object of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Point class by calling cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 function point_new(). As a final note, instantiating final or derivable class is cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 same.

The code for this example can be found on GitHub.

Instantiate a singleton object


One feature used by NetworkManager a lot are singleton objects. Namely, some objects control system wide resources and thus cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re is a need to have a single object control a single resource. For example, main component of a NetworkManager is cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 object NM_TYPE_MANAGER and it is necessary to have only one such object. There is also a single object for a configuration held in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 object/class NM_TYPE_CONFIG.

So, how is singleton object created? NetworkManager has some infrastructure that makes this task really simple. You start with a regular class/object. Then in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 C file with an object implementation you should call cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 following two macros/functions:
NM_DEFINE_SINGLETON_INSTANCE (NMNetnsController);
NM_DEFINE_SINGLETON_REGISTER (NMNetnsController);
Then, in function that allocates an object, you have a variable singleton_instance that should be NULL until cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 object is created and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n it should contain a pointer to a singleton object. Additionally, after creating object, you should call function nm_singleton_instance_register().

You are tasked with taking care that no new object of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 given type is created, i.e. you can shoot yourself in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 foot in case you don't take care to check cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 content of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 variable singleton_instance. singleton_instance is a file global variable declared by cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 macros shown above.

Private attributes


The next step is to add private attributes to our class. Let's suppose that we need to add x and y coordinates. In C++ we would modify cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 class declaration in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 following way:
class Point {
private:
        int x, y;
}
And that's basically it for C++ version. In case of C/GObject, you would define struct for private data in C file (point.c) with cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 following content:
typedef struct _PointPrivate PointPrivate;

struct _PointPrivate {
        int x, y;
};
First, observe that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 structure is placed in C file, not in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 header file. The reason is that this is private/internal structure so no users of a class should know cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 content of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 given structure. Furcá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365rmore, keep in mode that this structure isn't required to be called as shown in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 example by cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 GObject system, you can call it whatever you want, but it is a good practice and strongly suggested to add Private suffix to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 object name for cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 readability reasons.

Private part for cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 object should be allocated when cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 class is initialized. To achieve that add cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 following line in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 class initialization function, i.e. in point_class_init() function:
g_type_class_add_private (klass, sizeof (PointPrivate));
Before finishing with private attributes, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re is one more thing we need to discuss, and that is how to access private part of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 object. For that purpose it is good to declare cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 following macro:
#define POINT_GET_PRIVATE(object)      \
          (G_TYPE_INSTANCE_GET_PRIVATE((object), TYPE_POINT, PointPrivate))
This macro takes cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 pointer to an object and returns pointer to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 private data of a given object. Note that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 last argument to G_TYPE_INSTANCE_GET_PRIVATE is type (structure definition) of a private data. So, when you have a method that accesses cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 object's private data you would, at cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 start of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 method, call cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 mentioned macro to obtain pointer to private data structure and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n you would access it as usual.

The code for this example can be found on GitHub.

Public methods


After we added private attributes we want to add public methods that will allow us to get and set cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 values for cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 given private attributes. So, in C++ we would modify Point class definition as follows:
class Point {
private:
        int x, y;
public:
        void setValue(int x, int y);
        int getx(void);
        int gety(void);
};
The public methods should be defined in a C++ file (i.e. Point.cpp):
#include "Point.h"

void Point::setValue(int x, int y)
{
        this->x = x;
        this->y = y;
}

int Point::getx(void)
{
        return this->x;
}

int Point::gety(void)
{
        return this->y;
}
And, obviously, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 methods would be used in a following way in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 main function:
point->setValue(1, 1);
std::cout << "x=" << point->getx() << ", y=" << point->gety() << std::endl;
Now, to achieve cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 same with GObject system several changes to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 existing C code are necessary. First, we'll define a helper macro in a C file (point.c) that we will use to obtain private data of an object of class Point:
#define POINT_GET_PRIVATE(object)      \
          (G_TYPE_INSTANCE_GET_PRIVATE((object), TYPE_POINT, PointPrivate))
Next, public methods are just global functions with a prefix of a object name and with cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 first argument being cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 pointer to an object of a given class. In our case, we have three public methods each with cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 following prototype:
void point_set_value(Point *point, int x, int y);
int point_get_x(Point *point);
int point_get_y(Point *point);
Those declaration should go into cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 header file (point.h) because cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365y are accessible to any user of object Point, while cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365ir definitions should go into cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 C file (point.c):
void point_set_value(Point* point, int x, int y)
{
        PointPrivate* priv = POINT_GET_PRIVATE(point);

        priv->x = x;
        priv->y = y;
}

int point_get_x(Point* point)
{
        PointPrivate* priv = POINT_GET_PRIVATE(point);

        return priv->x;
}

int point_get_y(Point* point)
{
        PointPrivate* priv = POINT_GET_PRIVATE(point);

        return priv->y;
}
Finally, you should use those public methods after object of class Point is allocated in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 main function. Here is cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 example:
point_set_value(point, 1, 1);
printf("x=%d, y=%d\n", point_get_x(point), point_get_y(point));
And that's it. The code for this example can be found in GitHub repository.

Virtual methods


The methods implemented using GObject in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 previous section are non-virtual public methods. They are easy to implement, but cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 least flexible. So, to implement public virtual methods in GObject we need to:
  1. In class structure (PointClass) add function pointer for each virtual method we need.
  2. In header file declare dispatcher methods that will be called by cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 user of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 class.
  3. Define dispatcher methods in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 source file.
  4. Define implementation of virtual methods in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 source file.
  5. Initialize function pointers with cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 implementation of virtual methods.
Here are cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 steps in more details with cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 concrete example of Point class. Before continuing, note that virtual methods are possible only in derivable classes, not in final!

Step 1 is to add function pointer fields in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 class structure. That means that you class structure definition has to have cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 following format:
typedef struct _PointClass
{
        GObjectClass parent_class;
        void (*set_value) (Point *self, int x, int y);
        int (*get_x) (Point *self);
        int (*get_y) (Point *self);
} PointClass;
Note cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 bold parts, those are function pointer that will point to implementation of virtual methods. Each method takes, as cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 first argument, pointer to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 object it has to act upon.

Step 2 is to declare dispatcher methods. Those are very similar to non-virtual public methods in appearance, i.e. cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 name consists of a object name prefix and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 function name. Again, this is recommended, not something that is mandated by GObject system. Anyway, in our case those are cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 lines you have to add to header file:
void point_set_value(Point* self, int x, int y);
int point_get_x(Point* self);
int point_get_y(Point* self);
Step 3 is to define dispatcher methods in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 source file. I'll do it only for one method, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 rest are cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 same. So, in case of point_set_value() it would look like this:
void point_set_value(Point* self, int x, int y)
{
PointClass *klass;
klass = _POINT_GET_CLASS(self);
klass->set_value(self, x, y);
}
As you can see, what cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 method does is it access class definition, and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n invokes appropriate function through its pointer. I have to stress here two things:
  1. I skipped assertions, i.e. if cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 object/classes are of right type!
  2. Note cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 leading underscore in _POINT_GET_CLASS. It is cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 consequence of skipping module name when calling G_DECLARE_DERIVABLE_TYPE macro, i.e. I skipped third argument!
So, any user of a class will call those public methods which will dispatch cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 call to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 real method.

In step 4 we have to define implementation of virtual methods in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 source file. Again, I'll show it only for a single method. Also, you'll note that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 implementation is cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 same as for non-virtual public methods. Only we have to call cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365m differently so that compiler can differentiate between different function. I decided to use prefix objectname_private_, but it is my choice. I didn't manage to find something recommended by GObject. So, here it goes for cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 function to set value:
void point_private_set_value(Point* self, int x, int y)
{
PointPrivate *priv = POINT_GET_PRIVATE(self);
priv->x = x;
priv->y = y;
}
Finally, step 5 is to initialize pointers to dispatchers which in turn will call real methods. This has to be done by modifying definition of PointClass structure (or class structure in general). Here is how this structure should look like:
static void
point_class_init (PointClass* klass)
{
g_type_class_add_private (klass, sizeof (PointPrivate));
klass->set_value = point_private_set_value;
klass->get_y = point_private_get_y;
klass->get_x = point_private_get_x;

}
Note that we have cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 part that adds private data for cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 objects. The bold parts are cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 ones that initialize virtual functions.


Inheritence and subclassing


Inheritance allows for specialization of some class without touching that class internals. It is one of very important OO mechanisms and as such it is also supported in GObject and used by, e.g. NetworkManager.

So, suppose we want to define 3D point by basing its implementation on Point class while in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 same time adding only z coordinate. In C++ we would declare new class and say explicitly that we inherit base class Point:
#include "Point.h"

class Point3D: public Point
{
private:
        int z;
public:
        void setValue(int x, int y, int z);
        int getz(void);
}
As you can see we include declaration of 2D point and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n we add third coordinate as well as new methods, one to retrieve cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 third coordinate and anocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r one to be able to set all three coordinates. There is also definition (i.e. implementation) of a new class which is placed in Point3D.cpp file:
#include "Point3D.h"

void Point3D::setValue(int x, int y, int z)
{
        Point::setValue(x, y);
        this->z = z;
}

int Point3D::getz(void)
{
        return this->z;
}
Note how cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 base class method is called, by prefixing cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 method name with cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 base class name.

As usual, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 question is how this is done in C using GObject library. First, GObject make distinction between final and derivable classes, as we already saw above. Base class must be derivable, while subclass might be eicá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r final or derivable.

So, we are going to define derivable class Point as follows:
#include

#define TYPE_POINT (point_get_type())
G_DECLARE_DERIVABLE_TYPE(Point, point, , POINT, GObject)

typedef struct _PointClass {
        GObjectClass parent_class;
} PointClass;

Point* point_new(void);

void point_set_value(Point *point, int x, int y);
int point_get_x(Point *point);
int point_get_y(Point *point);
This is almost cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 same as original Point declaration we had. The implementation part isn't changed. Now, Point3D is declared as follows:
#include
#include "point.h"

#define TYPE_POINT3D (point3d_get_type())
G_DECLARE_FINAL_TYPE(Point3D, point3d, , POINT3d, Point)

typedef struct _Point3D {
        Point parent_instance;
} Point3D;

Point3D* point3d_new(void);

void point3d_set_value(Point3D* point, int x, int y, int z);
int point3d_get_z(Point3D* point);
Note cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 last parameter in G_DECLARE_FINAL_TYPE is Point. Basically, that's cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 base class and up until now we had cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re GObject from which all object descend.

Defining and implementing interfaces


Interfaces in OO languages are used as a form of a contract between different components. Some languages, as Java for example, have direct support for defining interfaces, while ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365rs, like C++, don't have and instead use some indirect methods. Here I would like to show how interfaces are implemented in GObject and for that purpose I'll declare interface that will be implemented by Point class used so far for examples. We'll start with C++, as usual.

To define interface in C++ abstract classes are used. Abstract class can not be instantiated because it has at least one pure virtual method that needs to be implemented by subclass. So, here is how interface for Point class would look like in C++:
class PointInterface {
public:
virtual void setValue(int x, int y) = 0;
virtual int getx(void) = 0;
virtual int gety(void) = 0;
};
As you can see, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 pure virtual method is declared by having "equal zero" addition. Now, just one more change is necessary and that is to declare that Point class implements this interface/abstract class. To do that only a single change is necessary, i.e.:
class Point : public PointInterface { ... }
In ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r words, Point inherits PointInterface.

So, how to do this in GObject? Here is cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 official documentation and we are going to do this for our existing Point class.

TBC...

Constructor


In cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 previous examples we already saw constructors, class constructor (*_class_init) and object constructor (*_init). Class constructor is called only once, when a first object of a given class is instantiated. Object constructor, on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r hand, is called every time an object of a given class is instantiated. You can easily see this modifying cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 previous example so that you place printf() statements into appropriate constructors (point_class_init() for a class constructor and point_init() for an object constructor). Then, by creating two objects of a Point class you'll clearly see that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 class constructor is called only once, while cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 object constructor is called as many times as you instantiated objects.

Destructor


Destructor isn't necessary



Object/class initialization and removal

When creating a new object using g_object_new() function cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re is a certain sequence of steps executed. For an object that is first of its class, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 sequence is:

  1. _class_init()
  2. constructor()
  3. constructed()
  4. _init()

Of those four, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 first and fourth, are mandatory and have to be defined in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 source. The second and third steps are optional and you define cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365m in class constructor (_class_init()) by assigning appropriate pointers to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 class interface.

Note that g_object_new() accepts an object type that should be created and a sequence of attribute-value pairs terminated with a single NULL. Those attribute-value pairs are used to set properties of an object (installed using g_object_class_install_property() function) but only after object constructor finishes. Also, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 additional requirement is to define set_property class method that will be called to set each property.

For objects of next type only object constructor is called and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n properties are initialized.

When object is removed cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n its destructor is called, if it exists. If this is cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 last object of its class, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n finalize method is called, again, if it exists.

Name spaces


TBD


Literature

If you try to Google for GObject examples or tutorials you'll find some materials from Gnome Web site. But, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 truth is that those tutorials leave some open questions and it is really hard to find something else. In cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 end I managed to find some references that I think are very valuable so here cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365y are:

Saturday, January 2, 2016

Processing RA messages in NetworkManager

The goal of this post is to analyze processing of RA messages through cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 NetworkManager code, starting with cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 initial reception all cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 way through cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 assignment of parameters to a device through which cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 RA was received. As a special case will also take a look what happens when RS is sent, i.e. what is different in comparison to unsolicited RAs. But first, we'll take a look at cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 relevant code organization and initialization process.

Code to process RAs and initialization phase


For receiving RA and sending RA NetworkManager uses libndp library. This library is used in class NM_TYPE_LNDP_RDISC (defined in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 file src/rdisc/nm-lndp-rdisc.c) which is a platform specific class tailored for cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Linux OS. This class inherits from class NM_TYPE_RDISC (defined in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 file src/rdisc/nm-rdisc.c) which is a platform independent base class. It contains functionality that is platform independent so cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365oretically NetworkManager can be more easily ported to, e.g. FreeBSD.

To create a new object of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 type NM_TYPE_LNDP_RDISC it is necessary to call function nm_lndp_rdisc_new(). This is, for example, done by cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 class NM_DEVICE_TYPE in function addrconf6_start() for each device for which IPv6 configuration is started.

Now, if NetworkManager will use RAs or not depends on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 configuration setting for IPv6 that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 user defines. If you go to configuration dialog for some network interface cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re is a setting for IPv6 configuration which might be ON or OFF. In case it is OFF, no IPv6 configuration will be done. If IPv6 configuration is enabled (switch placed in ON state) cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 specific configuration methods should be selected. The selected option is checked in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 function src/devices/nm-device.c:act_stage3_ip6_config_start(), where, depending on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 option selected, a specific initialization is started:
  • Automatic (method NM_SETTING_IP6_CONFIG_METHOD_AUTO)

    Start full IPv6 configuration by calling src/devices/nm-device.c:addrconf6_start() function.
     
  • Automatic, DHCP only (method NM_SETTING_IP6_CONFIG_METHOD_DHCP)

    Only configuration based on DHCP parameters received will be done. This type of configuration is initiated by calling function src/devices/nm-device.c:dhcp_start().
     
  • Manual (method NM_SETTING_IP6_CONFIG_METHOD_MANUAL)

    Manual configuration using parameters specified in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 configuration dialog and nothing else. The configuration of this type is initiated by calling function nm_ip6_config_new() which returns appropriate IPv6 configuration object.
     
  • Link-local Only (method NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL)

    Initiate only a link-local address configuration by calling function src/devices/nm-device.c:linklocal6_start().
Since in this post we are concerned with RA processing than we are obviously interested only in Automatic configuration type, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 one that calls addrconf6_start() function. This function, in turn, calls function src/nm-device.c:linklocal6_start() to ensure that link local configuration is present. It might happen that link local address isn't configured and so RA configuration must wait, or link local configuration is still present. In eicá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r case, when link local configuration is present RA processing can start. RA processing is kicked off by calling src/nm-device.c:addrconf6_start_with_link_ready() which in turn calls src/nm-rdisc.c:nm_rdisc_start() to kick off RA configuration.

nm_rdisc_start() is called with a pointer to NM_LNDP_RDISC class (defined in src/rdisc/nm_lndp_rdisc.c). Note that a method (nm_rdisc_start()) from a base class (NM_RDISC_TYPE, defined in src/rdisc/nm_rdisc.c) is called with a pointer to a subclass of a NM_RDISC_TYPE! Method in a base class does cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 following:
  1. Checks that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re is a subclass which defined virtual method start() (gassert(klass->start)).
  2. Initializes timeout for cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 configuration process. If timeout fires, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n rdisc_ra_timeout_cb() will be called that emits NM_RDISC_RA_TIMEOUT signal.
  3. Invokes a method start() from a subclass. Subclass is, as already said, NM_LNDP_RDISC and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 given method registers a callback src/rdisc/nm-lndp-rdisc.c:receive_ra() with libndp library. The callback is called by libndp library whenever RA is received.
  4. Starts solicit process by invoking solicit() method. This method schedules RS to be sent in certain amount of time (variable next) by send_rs() method. This method, actually, invokes send_rs() method from a subclass (src/nm-rdisc/nm-rdisc-linux.c:send_rs()) which sends RS using libndp library. Note that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 number of RSes sent is bounded and after certain amount of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365m sent cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 process is stopped under cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 assumption that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re is no IPv6 capable router on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 network.
  5. After RA has been received and processed cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 application of configuration parameters is done in src/device/nm-device.c:rdisc_config_changed() method. This callback is achieved by registering to NM_RDISC_CONFIG_CHANGED signal that is emitted by src/rdisc/nm-rdisc.c class whenever IPv6 configuration changes.
So, in conclusion, when link local configuration is finished, RA processing is started. The RA processing consists of waiting for RA in src/rdisc/nm-lndp-rdisc.c:receive_ra(). If RA doesn't arrive is certain amount of time cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n RS is sent in function src/nm-rdisc/nm-rdisc-linux.c:send_rs().

RA processing


When RA is received it is processed by cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 function src/rdisc/nm-lndp-rdisc.c:receive_ra(). The following configuration options are processed from RA by cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 given function:
  1. DHCP level.
  2. Default gateway.
  3. Addresses and routes.
  4. DNS information (RDNSS option).
  5. DNS search list (DNSSL option).
  6. Hop limit.
  7. MTU.
All cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 options that were parsed are stored (or removed from) a private attributes of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 base object (NMRDisc defined in src/rdisc/nm-rdisc.h).

Finally, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 method src/nm-rdisc.c:nm_rdisc_ra_received() is called to cancel all cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 timeouts. It will also emit signal NM_RDISC_CONFIG_CHANGED that will trigger application of received configuration parameters to a networking device.

Processing RS/RA


The RS/RA processing differs only by cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 fact that RS is sent after certain amount of time has passed and RA wasn't received, as described in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Code to process RAs and initialization phase section. After RS is sent, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 RA processing is cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 same as it would be without RS being sent.

Applying IPv6 configuration data


Application of received IPv6 configuration data is done in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 method src/device/nm-device.c:rdisc_config_changed(). IPv6 configuration is stored in IPv6 configuration object NM_TYPE_IP6_CONFIG defined in src/nm-ip6-config.c.

Note that this isn't cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 real application of configuration data, but only that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 configuration data is stored in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 appropriate object.

The function that really applies configuration data is src/devices/nm-device.c:ip6_config_merge_and_apply().

About Me

scientist, consultant, security specialist, networking guy, system administrator, philosopher ;)

Blog Archive