summaryrefslogtreecommitdiff
path: root/src/platform/nm-platform.h
Commit message (Collapse)AuthorAgeFilesLines
* platform: fix TC to-string/hash/cmp functions to include the actionThomas Haller2017-12-111-0/+2
| | | | | Also add a define NM_PLATFORM_ACTION_KIND_SIMPLE. It makes the uses of "simple" grepable.
* platform: add support for traffic filtersLubomir Rintel2017-12-111-0/+37
|
* platform: add support for queueing disciplinesLubomir Rintel2017-12-111-0/+26
|
* platform: merge nm_platform_*_delete() delete functionsThomas Haller2017-12-111-5/+5
| | | | | | | | | | | | | It only makes sense to call delete() with NMPObjects that we obtained from the platform cache. Otherwise, if we didn't get it from the cache in the first place, we wouldn't know what to delete. Hence, the input argument is (almost) always an NMPObject in the first place. That is different from add(), where we might create a new specific NMPlatform* instance on the stack. For add() it makes slightly more sense to have different functions depending on the type. For delete(), it doesn't.
* device: restore original dynamic IPv6 configuration on reapplyBeniamino Galvani2017-12-061-0/+2
|
* platform: consider RTNH_F_ONLINK onlink flag for IPv4 routesThomas Haller2017-11-131-1/+2
| | | | | | | | | | The "onlink" flag for IPv4 routes is part of the route ID. Consider it in nm_platform_ip4_route_cmp(). Also, allow configuring the flag when adding a route. Note that for IPv6, the onlink flag is still ignored. Pretty much like kernel does.
* platform: track all rtm_flags for routesThomas Haller2017-11-131-7/+11
|
* platform: add generic NM_PLATFORM_IP_ROUTE_CAST() macroThomas Haller2017-11-131-16/+4
| | | | A cast macro, that does some static type checking (of the pointer).
* platform: return platform error code from nm_platform_link_set_mtu()Thomas Haller2017-10-241-2/+2
|
* platform: downgrade warning about failure to set MTUThomas Haller2017-10-231-0/+1
| | | | | | | Setting the MTU failes under regular conditions, for example when setting the MTU of a master larger then the MTU of the slaves. Logging a warning it too alarming.
* core: refactor hashing to use reduce calls to siphash24_compress()Thomas Haller2017-10-181-1/+1
| | | | | This makes for example nm_platform_link_hash_update() by roughly 25% faster.
* all: extend hash functions with an NMHashState argumentThomas Haller2017-10-181-26/+14
| | | | | | | | | | | We often want to cascade hashing, meaning, to combine the outcome of various hash functions in a larger hash. Instead of having each hash function return a guint hash value, accept a hash state argument. This saves the overhead of initializing and completing the intermediate hash states. It also avoids loosing entropy when we reduce the larger hash state into the intermediate guint hash value.
* platform: detect kernel support for RTA_PREF to set router preference of ↵Thomas Haller2017-10-121-0/+1
| | | | IPv6 routes
* platform: support pref option for IPv6 routes (RTA_PREF)Thomas Haller2017-10-121-0/+6
| | | | Support IPv6 router preference (RFC4191) in platform code.
* platform: refactor detecting kernel supportThomas Haller2017-10-121-4/+9
| | | | | We are going to add another parameter to check. Instead of adding multiple virtual functions, add a NMPlatformKernelSupportFlags flags enum.
* libnm,core: add TABLE attribute for routes settingsThomas Haller2017-09-261-1/+2
| | | | https://bugzilla.redhat.com/show_bug.cgi?id=1436531
* core: inject route list to delete for nm_platform_ip_route_sync()Thomas Haller2017-09-261-2/+6
| | | | | | | | | | | | | | | | | Whenever we call a platform operation that reads or writes the netlink socket, there is the possibility that the cache gets updated, as we receive netlink events. It is thus racy, if nm_platform_ip_route_sync() *first* adds routes, and then obtains a list of routes to delete. The correct approach is to determine which routes to delete first (and keep it in a list @routes_prune), and pass that list down to nm_platform_ip_route_sync(). Arguably, this doesn't yet solve every race. For example, NMDevice calls update_ext_ip_config() during ip4_config_merge_and_apply(). That is good, as it resyncs with platform. However, before calling nm_ip4_config_commit() it calls other platform operations, like _commit_mtu(). So, the race is still there.
* platform: handle route table RT_TABLE_UNSPEC speciallyThomas Haller2017-09-261-5/+50
| | | | | | Kernel does not allow to add a route with table 0 (RT_TABLE_UNSPEC). It effectively is an alias for the main table. We must consider that when comparing routes sementically.
* core: workaround configuring IPv6 routes with "src" (RTA_PREFSRC)Thomas Haller2017-09-151-1/+2
| | | | | | | | | | | | | | | | | | | | | Kernel does not allow to add IPv6 routes with "src", as long as the corresponding address is still tentative (related bug rh#1457196). The workaround for this is cumbersome. First, when we fail to add such a route with "pref_src", we guess that it happend due to this issue. In that case, nm_ip6_config_commit() returns the list of routes that could not be added for the moment (but hopefully can be added later). We track this list in NMDevice, and keep trying to merge the routes back into ip6_config. In order to not try indefinitely, keep track of a timestamp when we tried to add this route for the first time. Another uglyness is that pending tentative routes don't explicitly block activation. In practice they may do, because for these routes we also have an IPv6 address that is still doing DAD, so the IP configuration is still pending due to that. https://bugzilla.redhat.com/show_bug.cgi?id=1452684
* core: track routes with source RTPROT_KERNEL (rtm_protocol) in ↵Thomas Haller2017-09-131-2/+2
| | | | | | | | | | | | | | | | NMIP4Config/NMIP6Config Let's not treat those routes special. I think this was originally done, because we relied on kernel to add the IPv4 device route, so we would ignore RTPROT_KERNEL routes and not delete them. We want to track them for various reasons: - for consistency, there is nothing special except that they might be added by kernel. - we expose the routes of NMIP4Config/NMIP6Config on D-Bus. That should include also routes such as device routes. Note, this commit changes that we now expose device routes on D-Bus too.
* core: adjust route equality for NMIP4Config/NMIP6Config to what kernel doesThomas Haller2017-09-131-5/+0
| | | | | | | | | | | | | | | | | | | For kernel, route ID compare identical according to NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID. Well, mostly. In practice, NM ignores several route properties that kernel considers part of the ID too. This leaves the possibility that kernel allows addition of two routes that compare idential for NetworkManager. Anyway, NMIP4Config/NMIP6Config should use the same equality as platform cache. Otherwise, there is the odd situation that ip-config merges routes that are treated as different by kernel. For IP addresses the ID operator already corresponded to what kernel does. There is no change for addresses. Note that NMSettingIPConfig also uses a different algorithm for comparing routes. But that doesn't really matter here, it it differed before too.
* platform/trivial: add code commentsThomas Haller2017-09-081-1/+4
|
* platform: add oif argument to nm_platform_ip_route_get()Thomas Haller2017-09-071-0/+2
| | | | Analog to `ip route get $DST oif $IFACE`.
* platform: add support for routing tables to platform cacheThomas Haller2017-08-241-0/+30
| | | | | The upper layers still ignore all routes outside the main table. For now, just add support to NMPlatform.
* platform: add option to suppress error message from nm_platform_ip_route_add()Thomas Haller2017-08-241-0/+9
| | | | | | When an error happens, we want to print a better message. Avoid duplicate error messages by adding a flag to suppress logging in the lower layer.
* platform: pass string buffer to nm_platform_error_to_string() and print ↵Thomas Haller2017-08-241-2/+5
| | | | | | | | | | numeric errno Change the output of nm_platform_error_to_string() to print the numeric value. Also, accept a string buffer instead of using an alloca() allocated buffer. There is still a macro to provide the previous functionality, but it was ill-suited to call from inside a loop.
* platform: return failure reason from route-add and return only netlink responseThomas Haller2017-08-241-9/+10
| | | | | | | | | | | | | | | | | | | | | | | Let nm_platform_ip_route_add() and friends return an NMPlatformError failure reason. Also, do_add_addrroute() did not return the response from kernel. Instead, it determined success/failure based on the presence of the object in the cache. That is racy and does not allow to give a failure reason from kernel. Instead, determine success solely based on the netlink reply from kernel. The received errno shall be authorative, there is no need to second guess the response. There is a problem that netlink is not a reliable protocol. In case of receive buffer overflow, the response is lost and we don't know whether the command succeeded (it likely did). It's unclear how to fix that, but for now just return "unspecified" error. We probably avoid that already by having a huge buffer size. Also, downgrade the error message to <warn> level. <error> is really for bugs only.
* platform: add nm_platform_ip_route_get() for route-lookupThomas Haller2017-08-241-0/+10
| | | | | | | | | | | | Inspired from iproute2. As such, don't use libnl3's "struct nl_msg", but add _nl_addattr_l() and use a stack-allocated "struct nlmsghdr". With this, we are closer to the raw netlink API. It really is simple enough. The complicated part of the patch is that we re-use the existing netlink socket for events. Hence, we must process the socket via our common event_handler_recvmsgs(). That also means, that we get the netlink response a few layers down the stack and have to return the result via DelayedActionWaitForNlResponseData.
* platform: add non-exclusive routes and drop route-managerThomas Haller2017-08-241-5/+16
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Previously, we would add exclusive routes via netlink message flags NLM_F_CREATE | NLM_F_REPLACE for RTM_NEWROUTE. Similar to `ip route replace`. Using that form of RTM_NEWROUTE message, we could only add a certain route with a certain network/plen,metric triple once. That was already hugely inconvenient, because - when configuring routes, multiple (managed) interfaces may get conflicting routes (multihoming). Only one of the routes can be actually configured using `ip route replace`, so we need to track routes that are currently shadowed. - when configuring routes, we might replace externally configured routes on unmanaged interfaces. We should not interfere with such routes. That was worked around by having NMRouteManager (and NMDefaultRouteManager). NMRouteManager would keep a list of the routes which NetworkManager would like to configure, even if momentarily being unable to do so due to conflicting routes. This worked mostly well but was complicated. It involved bumping metrics to avoid conflicts for device routes, as we might require them for gateway routes. Drop that now. Instead, use the corresponding of `ip route append` to configure routes. This allows NetworkManager to confiure (almost) all routes that we care. Especially, it can configure all routes on a managed interface, without replacing/interfering with routes on other interfaces. Hence, NMRouteManager becomes obsolete. It practice it is a bit more complicated because: - when adding an IPv4 address, kernel will automatically create a device route for the subnet. We should avoid that by using the IFA_F_NOPREFIXROUTE flag for IPv4 addresses (still to-do). But as kernel may not support that flag for IPv4 addresses yet (and we don't require such a kernel yet), we still need functionality similar to nm_route_manager_ip4_route_register_device_route_purge_list(). This functionality is now handled via nm_platform_ip4_dev_route_blacklist_set(). - trying to configure an IPv6 route with a source address will be rejected by kernel as long as the address is tentative (see related bug rh#1457196). Preferably, NMDevice would keep the list of routes which should be configured, while kernel would have the list of what actually is configured. There is a feed-back loop where both affect each other (for example, when externally deleting a route, NMDevice must forget about it too). Previously, NMRouteManager would have the task of remembering all routes which we currently want to configure, but cannot due to conflicting routes. We get rid of that, because now we configure non-exclusive routes. We however still will need to remember IPv6 routes with a source address, that currently cannot be configured yet. Hence, we will need to keep track of routes that currently cannot be configured, but later may be. That is still not done yet, as NMRouteManager didn't handle this correctly either.
* platform: add and use nm_platform_ip_route_normalize()Thomas Haller2017-08-231-0/+3
| | | | | Adding a route to kernel may coerce/mangle some properties. Add a function nm_platform_ip_route_normalize() to simulate these changes.
* platform: cleanup and renaming of nm_platform_address_flush() functionThomas Haller2017-08-231-1/+3
| | | | | | | | | | | | Rename to nm_platform_ip_address_flush(), it's more consistent with naming for other platform functions. Also, pass an address family argument. Sometimes I feel an option makes it clearer what the function does. Otherwise, from the name it's not clear which address families are affected. As an API, it feels more correct to me. We soon also get a nm_platform_ip_route_flush() function, which will look similar.
* platform: add typedef for NMPObjectPredicateFunc function pointerThomas Haller2017-08-231-1/+4
| | | | Otherwise, casting a function pointer is cumbersome.
* platform: add nm_platform_ip_route_add() functionThomas Haller2017-08-231-0/+3
|
* platform: use _Generic() for NM_PLATFORM_IP_ROUTE_IS_DEFAULT() macroThomas Haller2017-08-231-0/+15
| | | | Avoid the plain cast and use _Generic() to check the type of @route argument.
* platform: fix cache to use kernel's notion for equality of routesThomas Haller2017-08-121-8/+0
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Until now, NetworkManager's platform cache for routes used the quadruple network/plen,metric,ifindex for equaliy. That is not kernel's understanding of how routes behave. For example, with `ip route append` you can add two IPv4 routes that only differ by their gateway. To the previous form of platform cache, these two routes would wrongly look identical, as the cache could not contain both routes. This also easily leads to cache-inconsistencies. Now that we have NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID, fix the route's compare operator to match kernel's. Well, not entirely. Kernel understands more properties for routes then NetworkManager. Some of these properties may also be part of the ID according to kernel. To NetworkManager such routes would still look identical as they only differ in a property that is not understood. This can still cause cache-inconsistencies. The only fix here is to add support for all these properties in NetworkManager as well. However, it's less serious, because with this commit we support several of the more important properties. See also the related bug rh#1337855 for kernel. Another difficulty is that `ip route replace` and `ip route change` changes an existing route. The replaced route has the same NM_PLATFORM_IP_ROUTE_CMP_TYPE_WEAK_ID, but differ in the actual NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID: # ip -d -4 route show dev v # ip monitor route & # ip route add 192.168.5.0/24 dev v 192.168.5.0/24 dev v scope link # ip route change 192.168.5.0/24 dev v scope 10 192.168.5.0/24 dev v scope 10 # ip -d -4 route show dev v unicast 192.168.5.0/24 proto boot scope 10 Note that we only got one RTM_NEWROUTE message, although from NMPCache's point of view, a new route (with a particular ID) was added and another route (with a different ID) was deleted. The cumbersome workaround is, to keep an ordered list of the routes, and figure out which route was replaced in response to an RTM_NEWROUTE. In absence of bugs, this should work fine. However, as we only rely on events, we might wrongly introduce a cache-inconsistancy as well. See the related bug rh#1337860. Also drop nm_platform_ip4_route_get() and the like. The ID of routes is complex, so it makes little sense to look up a route directly.
* platform: add nm_platform_link_set_name()Beniamino Galvani2017-08-051-0/+2
| | | | We'll need it to rename the new PPP interface to a given name.
* platform: extend API for adding routesThomas Haller2017-08-031-5/+32
| | | | | | | | | | | | | | | | | | | | Via the flags of the RTM_NEWROUTE netlink message, kernel and iproute2 support various variants to add a route. - ip route add - ip route change - ip route replace - ip route prepend - ip route append - ip route test Previously, our nm_platform_ip4_route_add() function was basically `ip route replace`. In the future, we should rather user `ip route append` instead. Anyway, expose the netlink message flags in the API. This allows to use the various forms, and makes it also more apparent to the user that they even exist.
* platform,libnm: cleanup handling of TOS for routesThomas Haller2017-08-031-1/+8
| | | | | | | | | | - kernel ignores rtm_tos for IPv6 routes. While iproute2 accepts it, let libnm reject TOS attribute for routes as well. - move the tos field from NMPlatformIPRoute to NMPlatformIP4Route. - the tos field is part of the weak-id of an IPv4 route. Meaning, `ip route add` can add routes that only differ by their TOS.
* core: implement NMIP4Config's and NMIP6Config's route equality based on ↵Thomas Haller2017-08-031-0/+5
| | | | | | | | | | | nm_platform_ipx_route_cmp() There are various notions of how to compare routes. Collect them all in nm_platform_ip4_route_cmp(), nm_platform_ip4_route_hash(), nm_platform_ip6_route_cmp(), and nm_platform_ip6_route_hash(). This way, we have them side-by-side, which makes the differences more discoverable.
* platform: cleanup handling metric paramters for non-exclusive routesThomas Haller2017-08-031-0/+9
|
* platform: cleanup handling locks for non-exclusive routesThomas Haller2017-08-031-10/+12
|
* platform: cleanup handling "window" for non-exclusive routesThomas Haller2017-08-031-7/+16
|
* platform: use route src/src_plen when deleting IPv6 routeThomas Haller2017-08-031-0/+8
|
* platform: use route pref_src when deleting IP routeThomas Haller2017-08-031-2/+11
|
* platform: use route mss when deleting IP routeThomas Haller2017-08-031-0/+10
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The mss (advmss, RTA_METRICS.RTAX_ADVMSS) is in a way part of the ID for IPv4 routes. That is, you can add multiple IPv4 routes, that only differ by mss. On the other hand, that is not the case for IPv6. Two IPv6 routes that only differ by mss are considered the same. Another issue is, that you cannot selectively delete an IPv4 route based on the mss: ip netns del x ip netns add x IP() { ip netns exec x ip "$@" } IP link add type veth IP link set veth0 name v IP link set veth1 up IP link set v up IP route append 192.168.7.0/24 dev v advmss 6 IP route append 192.168.7.0/24 dev v advmss 7 IP -d route show dev v IP route delete 192.168.7.0/24 dev v advmss 7 IP -d route show dev v It seems for deleting routes, kernel ignores mss (which doesn't really matter for IPv6, but does so for IPv4).
* platform: use correct gateway for deleting routeThomas Haller2017-08-031-0/+5
| | | | | Routes may only differ by their gateway. When deleting a route, we must specify the exact gateway to delete.
* platform: use correct scope for deleting IPv4 routeThomas Haller2017-08-031-4/+13
| | | | | | | | | | | | | | | | | | | | Refactor _nl_msg_new_route() to obtain the route scope (rtm_scope) from the NMPObject, instead of a separate argument. That way, when deleting an IPv4 route, we don't pick the first route that matches (RT_SCOPE_NOWHERE), but use the actual scope of the route that we want to delete. That matters, if there are more then one otherwise identical routes that only differ by their scope. For kernel, the scope of IPv6 routes is always global (RT_SCOPE_UNIVERSE). Also, during ip4_route_add() initialize the intermediate @obj to have the values as we expect them after adding the route. That is necessary to use it in _nl_msg_new_route(). But also nicer for consistency. Also, move the scope_inv field in NMPlatformIP4Route to let the other in_addr_t fields life side by side.
* platform: use proper rt_source of route for add and deleteThomas Haller2017-08-031-1/+9
| | | | | | | | | | | | | _nl_msg_new_route() should not get extra arguments, but instead use all parameters from the NMPObject argument. This will allow during nm_platform_ip_route_delete() to pick the exact route that should be deleted. Also, in ip4_route_add()/ip6_route_add(), keep the stack-allocated @obj object consistent with what we expect to add. That is, set the rt_source argument to the value of what the route will have after kernel adds it. That might be necessary, because do_add_addrroute() searches the cache for @obj.
* platform: add compare functions for routes with different compare semanticsThomas Haller2017-08-031-9/+64
| | | | | | | | | | Routes are complicated. `ip route add` and `ip route append` behaves differently with respect to determine whether an existing route is idential or not. Extend the cmp() and hash() functions to have a compare type, that covers the different semantics.
* platform: pass full route object to platform delete functionThomas Haller2017-07-251-6/+3
| | | | | | | | | | | | | | | | | | | | | | | | | | | | Contrary to addresses, routes have no ID. When deleting a route, you cannot just specify certain properties like network/plen,metric. Well, actually you can specify only certain properties, but then kernel will treat unspecified properties as wildcard and delete the first matching route. That is not something we want, because we need to be in control which exact route shall be deleted. Also, rtm_tos *must* match. Even if we like the wildcard behavior, we would need to pass TOS to nm_platform_ip4_route_delete() to be able to delete routes with non-zero TOS. So, while certain properties may be omitted, some must not. See how test_ip4_route_options() was broken. For NetworkManager it only makes ever sense to call delete on a route, if the route is already fully known. Which means, we only delete routes that we have already in the platform cache (otherwise, how would we know that there is something to delete). Because of that, no longer have separate IPv4 and IPv6 functions. Instead, have nm_platform_ip_route_delete() which accepts a full NMPObject from the platform cache. The code in core doesn't jet make use of this new functionality. It will in the future. At least, it fixes deleting routes with differing TOS.