Commit graph

439 commits

Author SHA1 Message Date
Thomas Haller
88213b2e6a platform: tighten return value from do_add_addrroute()
Only return TRUE, if the netlink request was responded with success and
the object exists after adding.
2015-12-17 18:42:53 +01:00
Thomas Haller
1a501c6456 platform: check for existing link in do_add_link_with_lookup()
When adding a link, that can only make sense if no such link
exists yet. Check for that condition first, to properly return
an error.
2015-12-17 18:42:53 +01:00
Thomas Haller
cea8f1a0f0 platform: change meaning of return value for delete-function
When deleting an object, we allow failure to delete a non-existing object.
Thus, the only thing we care about is whether the object is no longer
present after deletion. Adjust the return values to reflect that.
2015-12-17 18:42:53 +01:00
Thomas Haller
690732cfed platform: drop delayed_action idle handler
The idea was allowing pending delayed-actions and process them in an
idle handler. We dont want to do that, because whenever platform code
returns, we want to have no pending actions -- because otherwise the
platform cache might be in an inconsistent state.

Just drop it.
2015-12-17 18:42:51 +01:00
Thomas Haller
a29f438294 platform/trivial: rename internal field with netlink socket 2015-12-17 18:42:01 +01:00
Thomas Haller
412a50bd30 platform: inline event_handler_read_netlink() 2015-12-17 18:42:01 +01:00
Thomas Haller
d7782b9769 platform: drop synchronous netlink socket 2015-12-17 18:42:01 +01:00
Thomas Haller
c73b9f6529 platform: change links via event netlink socket 2015-12-17 18:42:01 +01:00
Thomas Haller
1097967077 platform: delete objects via event netlink socket 2015-12-17 18:42:01 +01:00
Thomas Haller
be28608a8f platform: add addresses and routes via event netlink socket 2015-12-17 18:42:01 +01:00
Thomas Haller
f8378800bb platform: add links via event netlink socket 2015-12-17 18:42:01 +01:00
Thomas Haller
dce5e6d815 platform: assert that delayed_action_handle_all() is not called recursively
We would not expect that delayed_action_handle_all() is called recursively.
Assert against that. If we ever happen to call it recursively, we would
need to take care of properly avoiding infinite loops or deep call
stacks.
2015-12-17 18:41:59 +01:00
Thomas Haller
6d67e6e9c4 platform: rework waiting for netlink response
Track pending netlink requests and properly report the resulting errno
back.

Currently we send only requests in do_request_link() and do_request_all().
These callers don't actually care about the result, all they care that the
request is answered before returning back from platform code to the caller.
Thus, up to now the tracking of the sequence number was pretty simple.

Later we also want to get the errno from a request, thus rework sending
requests to also remember about outstanding sequence numbers and
properly track muliple parallel requests.

Later the synchronous actions (e.g. add-link) will also be handled
via the asynchronous socket.
2015-12-17 18:32:15 +01:00
Thomas Haller
eb182c2e1c platform: minor refactoring in delayed_action_schedule() 2015-12-17 18:32:09 +01:00
Thomas Haller
c9e04c963e platform: implement our own sequence counter
Instead of using the one from libnl's socket.
2015-12-17 18:32:06 +01:00
Thomas Haller
4ea711e03e platform/trivial: remove obsolete code comment 2015-12-17 18:08:36 +01:00
Thomas Haller
ecdcfda0dd platform: cleanup event_handler_recvmsg() (rename event_valid_msg()) 2015-12-17 18:08:36 +01:00
Thomas Haller
6ee868678b platform: cleanup event_handler_recvmsg() (drop _nl_sock_flush_data())
Also avoids/fixes a bug in _nl_sock_flush_data() where we would loop
endlessly, if nl_recvmsgs() fails for reasons other then EAGAIN.
2015-12-17 18:08:36 +01:00
Thomas Haller
385e68327f platform: cleanup event_handler_recvmsg() (adjust log messages) 2015-12-17 18:08:36 +01:00
Thomas Haller
47773c80ac platform: cleanup event_handler_recvmsg() (inline event_err()) 2015-12-17 18:08:36 +01:00
Thomas Haller
c13163cd55 platform: cleanup event_handler_recvmsg() (move EAGAIN workaround) 2015-12-17 18:08:36 +01:00
Thomas Haller
bdd2c31d39 platform: cleanup event_handler_recvmsg() (inline verify_source()) 2015-12-17 18:08:36 +01:00
Thomas Haller
3e2d0d6968 platform: cleanup event_handler_recvmsg() (code-style) 2015-12-17 18:08:36 +01:00
Thomas Haller
2f6b5d4125 platform: reimplement nl_recvmsg() in platform
Calling nl_recvmsgs_default() leads dirctly to recvmsgs() from
"nl.c". This functions reads messages (recvmsg) in a loop and
invokes the callbacks.

Later we want to merge nlh and nlh_event, meaning that we must
anticipate parsing unrelated messages while waiting for an ACK.
While that would be possible by registering different callbacks
and letting them interact, it is actually more complicated. Just
assume full control over the message parsing.

Basically, copy recvmsgs() to event_handler_recvmsg(). For now just
copy the function and do little adjustment (to show the similarity
to the original). Cleanup follows.
2015-12-17 18:08:36 +01:00
Thomas Haller
be0f8e2854 platform/trivial: move code
sysctl handling is independent from netlink-cache. Move the code.
2015-12-17 18:08:36 +01:00
Thomas Haller
600a247f57 platform: refactor handling netlink message by manually inlining cache functions
There are only one caller of the two functions. It's shorter and simpler
just to implement the short functionality right there.
2015-12-12 22:18:28 +01:00
Thomas Haller
8a38b4dd13 platform: inline setup_socket() function
Constructing the sockets is already quite simple, yet distinct.
Later this distinction will become bigger, so unwrap setup_socket().
2015-12-12 12:34:29 +01:00
Thomas Haller
461cf0c571 platform: factor out completing and sending netlink message 2015-12-12 12:34:29 +01:00
Thomas Haller
9ce3733d0c platform: add const to input arguments to link-add functions
Some line-breaks and adding "const".
2015-12-11 14:14:13 +01:00
Thomas Haller
d2fab2df54 platform: EAGAIN is equal to EWOULDBLOCK
The macro EWOULDBLOCK is another name for EAGAIN; they are always the
  same in the GNU C Library.

  https://www.gnu.org/savannah-checkouts/gnu/libc/manual/html_node/Error-Codes.html

Otherwise, we would need a workaround for EWOULDBLOCK too, because
libnl maps that to NLE_FAILURE. So we would have to detect EAGAIN
as (nle == -NLE_FAILURE && errno == EWOULDBLOCK).
2015-12-10 17:53:04 +01:00
Thomas Haller
eeb7d20ee0 platform: fix memleak in _nl_sock_flush_data()
Fixes: 9a16ce0876
2015-12-10 17:13:48 +01:00
Thomas Haller
10b684b827 platform: fix event_handler_read_netlink_one() wrongly returning with nothing to read
When the errno was accidentally set to EAGAIN or EWOULDBLOCK,
we would only read one single message and return that there is
nothing to read.

This means, if there were more then one messages ready to read,
we would only read the first one and return to the main-loop
(which then again calls back to platform as more data is ready
to be read).
2015-12-10 17:13:48 +01:00
Thomas Haller
1a7b19ea6a platform: move reading sysctl-options for master/slave to NMPlatform
These functions are only helpers for accessing sysctl and independent
from NMLinuxPlatform. Move their implementation to the base class.
2015-12-10 14:33:49 +01:00
Thomas Haller
eef388990f platform/trivial: rename link related functions
Link related functions should have a "nm_platform_link" prefix. Rename.

Naming is a subjective matter and one might argue that omitting
the "link" part from the name is shorter and even preferred.

However, I think functions related to links should have a common
prefix as the underlyings are strongly related.
2015-12-10 14:33:49 +01:00
Thomas Haller
6a7730241b trival: fix whitespace 2015-12-10 14:33:49 +01:00
Thomas Haller
a4de9187ff platform: return pointer to NMPlatformLink object for add functions
Let the link-add functions return the internal pointer to the platform
link object. Similar to link-get, which doesn't copy the link either.

Also adjust the sole users of the add-functions (create-and-realize)
to take the pointer.

Eventually we still copy the returned data, because accessing platform can
invalidate the returned pointer. Thus we don't actually safe any copying
by this (at least every use of the function currently leads to the data
being copied).
Still change it, because I think the API of NMPlatform should look like that.
2015-12-10 14:33:49 +01:00
Beniamino Galvani
01e95c8c95 platform: add vxlan support
Add a new method to the platform code to create vxlan devices.
2015-12-09 16:36:46 +01:00
Beniamino Galvani
3871056019 platform: add macvtap link creation support 2015-12-09 14:30:08 +01:00
Beniamino Galvani
27c0f8def4 platform: add macvlan link creation support 2015-12-09 14:30:08 +01:00
Beniamino Galvani
c1be9856bf platform: return the macvlan mode as integer
It's easier to handle it as an integer than as a string.
2015-12-09 14:30:07 +01:00
Beniamino Galvani
32f6e1ef2e platform: add IP6TNL links support 2015-12-01 17:39:41 +01:00
Beniamino Galvani
30e648f981 platform: add IPIP links support 2015-12-01 17:39:41 +01:00
Beniamino Galvani
0754280b9f platform: add SIT links support 2015-12-01 17:39:41 +01:00
Beniamino Galvani
91bf0efaa7 platform: add GRE links creation support 2015-12-01 17:39:41 +01:00
Thomas Haller
832539a511 platform: emit signals by signal-id instead of string
We potentially emit a lot of signals. Don't look up the
signal by name because that adds quite some additional
overhead, like peeking for a GQuark.

Instead pass the numeric signal-id directly.
2015-11-27 15:17:44 +01:00
Thomas Haller
510e53ca16 platform: remove NMPlatformReason enum
This enum was unused and meaningless because the platform signals
are emitted as a consequence of netlink messages. It is not clear
whether a netlink message was received due to an external event
or an internal action.
2015-11-27 15:17:44 +01:00
Thomas Haller
8a87a91813 platform: cope differently with spurious RTM_DELLINK message when unslaving bridge-slave
Unslaving from a bridge causes a wrong RTM_DELLINK event for
the former slave.

    # ip link add dummy0 type dummy
    # ip link add bridge0 type bridge
    # ip link set bridge0 up
    # ip link set dummy0 master bridge0
    # ip monitor link &
    # ip link set dummy0 nomaster
    18: dummy0: <BROADCAST,NOARP> mtu 1500 qdisc noop master bridge0 state DOWN group default
        link/ether 76:44:5f:b9:38:02 brd ff:ff:ff:ff:ff:ff
    18: dummy0: <BROADCAST,NOARP> mtu 1500 master bridge0 state DOWN
        link/ether 76:44:5f:b9:38:02
    Deleted 18: dummy0: <BROADCAST,NOARP> mtu 1500 master bridge0 state DOWN
        link/ether 76:44:5f:b9:38:02
    18: dummy0: <BROADCAST,NOARP> mtu 1500 qdisc noop state DOWN group default
        link/ether 76:44:5f:b9:38:02 brd ff:ff:ff:ff:ff:ff
    19: bridge0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default
        link/ether 00:00:00:00:00:00 brd ff:ff:ff:ff:ff:ff
    19: bridge0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default
        link/ether 00:00:00:00:00:00 brd ff:ff:ff:ff:ff:ff

Previously, during do_request_link() we would remember the link that is
about to be requested (delayed_deletion) and delay processing a new
RTM_DELLINK message until the end of do_request_link() -- and possibly
forget about about the deletion, if RTM_DELLINK was followed by a
RTM_NEWLINK.

However, this hack does not catch the case where an external command
unslaves the link.

Instead just accept the wrong event and raise a "removed" signal right
away. This brings the cache in an externally visible, wrong state that
will be fixed by a following "added" signal.

Still do that because working around the kernel bug is complicated. Also,
we already might emit wrong "added" signals for devices that are already
removed. As a consequence, a user should not consider the platform signals
until all events are processed.
Listeners to that signal should accept that added/removed link changes
can be wrong and should preferably handle them idly, when the events
have settled.

It can even be worse, that a RTM_DELLINK is not fixed by a following
RTM_NEWLINK:

    ...
    # ip link set dummy0 nomaster
    36: dummy0: <BROADCAST,NOARP> mtu 1500 qdisc noop master bridge0 state DOWN
        link/ether e2:f2:20:98:3a:be brd ff:ff:ff:ff:ff:ff
    36: dummy0: <BROADCAST,NOARP> mtu 1500 master bridge0 state DOWN
        link/ether e2:f2:20:98:3a:be
    Deleted 36: dummy0: <BROADCAST,NOARP> mtu 1500 master bridge0 state DOWN
        link/ether e2:f2:20:98:3a:be
    37: bridge0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN
        link/ether 00:00:00:00:00:00 brd ff:ff:ff:ff:ff:ff
    37: bridge0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN
        link/ether 00:00:00:00:00:00 brd ff:ff:ff:ff:ff:ff

So, when a slave is deleted, we have to refetch it too.

https://bugzilla.redhat.com/show_bug.cgi?id=1285719
2015-11-27 15:14:55 +01:00
Thomas Haller
83240f24ae Revert "platform: cancel delayed action REFRESH_LINK when receiving an update"
On some kernels (at least RHEL-7.2) we receive a spurious RTM_NEWLINK
message after the RTM_DELLINK message for deleting a bond master.

On RHEL-7, the following commands give:

    # ip link add dummy0 type dummy
    # ip link add bond0 type bond
    # ip link set bond0 up
    # ip link set dummy0 master bond0
    # ip monitor link &
    # ip link del bond0
    21: bond0: <BROADCAST,MULTICAST,MASTER> mtu 1500 qdisc noqueue state DOWN
        link/ether 1e:a6:6c:81:c1:8d brd ff:ff:ff:ff:ff:ff
    Deleted 21: bond0: <BROADCAST,MULTICAST,MASTER> mtu 1500 qdisc noop state DOWN
        link/ether 1e:a6:6c:81:c1:8d brd ff:ff:ff:ff:ff:ff
    20: dummy0: <BROADCAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN
        link/ether 1e:a6:6c:81:c1:8d brd ff:ff:ff:ff:ff:ff
    21: bond0: <BROADCAST,MULTICAST,MASTER> mtu 1500 qdisc noop state DOWN
        link/ether da:ee:58:70:6f:e5 brd ff:ff:ff:ff:ff:ff

    ^^^^^^^^^^^^^^^ RTM_NEWLINK after RTM_DELLINK (and there follows no
    RTM_DELLINK afterwards)

    21: bond0: <BROADCAST,MULTICAST,MASTER> mtu 1500 qdisc noop state DOWN
        link/ether da:ee:58:70:6f:e5 brd ff:ff:ff:ff:ff:ff
    20: dummy0: <BROADCAST,NOARP> mtu 1500 qdisc noqueue state DOWN
        link/ether 1e:a6:6c:81:c1:8d brd ff:ff:ff:ff:ff:ff
    20: dummy0: <BROADCAST,NOARP> mtu 1500 qdisc noqueue state DOWN
        link/ether 1e:a6:6c:81:c1:8d brd ff:ff:ff:ff:ff:ff

Fix that by reverting clear_REFRESH_LINK(). This fix has two downsides:

- on kernels where this hack is not necessary, we unnecessarily refetch
  a link
- the platform cache first removes the link, adds it again and removes
  it. This is ugly, but should have no real consequences because all
  listeners to the platform signals delay processing the signals to an
  idle handler.

https://bugzilla.redhat.com/show_bug.cgi?id=1285719

This reverts commit f4f4e1cf09.
2015-11-27 14:38:12 +01:00
Thomas Haller
29c293728d platform/tests: add test for missing netlink notification for IFA_LINK_NETNSID
The related bug rh#1262908 in kernel causes missing netlink notifications
when moving a IFA_LINK interface to another netns.

Add a test for our workaround.

Related: https://bugzilla.redhat.com/show_bug.cgi?id=1262908
2015-11-27 14:38:12 +01:00
Thomas Haller
5650c82a8e platform: workaround kernel bug about missing IFLA_LINK/parent when creating veth
The related bug rh#1285827 in kernel causes a missing IFLA_LINK/parent
attribute when creating a veth pair:

    # ip monitor link &
    [1] 6745

    # ip link add dev vm1 type veth peer name vm2
    30: vm2@NONE: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN
        link/ether be:e3:b7:0e:14:52 brd ff:ff:ff:ff:ff:ff
    31: vm1@vm2: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN
        link/ether da:e6:a6:c5:42:54 brd ff:ff:ff:ff:ff:ff

Add a workaround and test.

Related: https://bugzilla.redhat.com/show_bug.cgi?id=1285827
2015-11-27 14:22:06 +01:00