Linx.Netlink.Rtnl.Link (Linx v0.1.0)

Copy Markdown View Source

rtnetlink network links (interfaces) — the RTM_*LINK messages.

A %Link{} is a decoded interface: its index, name, link-layer type, flags, MTU, MAC address, parent, master and kind-specific information. Read verbs list/1 / get/2 retrieve interfaces; mutating verbs create, delete and configure them.

Example

{:ok, sock} = Rtnl.open()

{:ok, links} = Link.list(sock)
# => [#Linx.Netlink.Rtnl.Link<"lo" (1) UP MTU=65536>,
#     #Linx.Netlink.Rtnl.Link<"eth0" (2) UP MTU=1500>]

# A veth pair: bring one end up, hand the peer to a container's netns.
:ok = Link.create_veth(sock, "ct0a", "ct0b")
:ok = Link.set_up(sock, "ct0a")
:ok = Link.move_to_netns(sock, "ct0b", container_pid)

Creating

Several kinds of virtual link are supported, each by its own constructor:

Link.create_macvlan(socket, name, parent, mode \\ :bridge)
Link.create_ipvlan (socket, name, parent, mode \\ :l3)
Link.create_veth   (socket, name, peer_name)
Link.create_vlan   (socket, name, parent, vlan_id)
Link.create_bridge (socket, name)
Link.create_dummy  (socket, name)

Configuring

set_up/2 / set_down/2 toggle IFF_UP; set_mtu/3, set_name/3, set_address/3 and set_master/3 change the MTU, name, MAC and bridge / bond master respectively; move_to_netns/3 hands the link to another network namespace.

Wire format

struct ifinfomsg (include/uapi/linux/rtnetlink.h) and the IFLA_* attributes (include/uapi/linux/if_link.h) — declared with the Linx.Netlink.Codec DSL. IFLA_LINKINFO is itself a sub-codec (Linx.Netlink.Rtnl.LinkInfo) whose IFLA_INFO_DATA is dispatched on the kind value, picking the right per-kind module (LinkInfo.Macvlan, LinkInfo.Veth, …).

Summary

Functions

Creates an empty Linux bridge named name.

Creates a dummy interface named name — a loopback-like virtual link with no real packet path, useful as a stable address holder or a test fixture.

Creates an ipvlan link named name on parent interface parent.

Creates a macvlan link named name on parent interface parent.

Creates a veth pair — two interfaces named name and peer_name, connected back-to-back.

Creates an vlan sub-interface named name on parent parent carrying 802.1Q VLAN tag vlan_id (1..4094).

Decodes a netlink message body into a t/0.

Deletes the link named name.

Encodes a t/0 into its netlink message body.

Gets the link named name.

Lists every link in the socket's network namespace.

Moves link name into the network namespace of process pid.

Sets link name's MAC address to mac — a colon-separated hex string, e.g. "aa:bb:cc:dd:ee:ff", or a Linx.MAC.

Brings link name administratively down (clears IFF_UP).

Enslaves link name to master_name — typically a bridge or bond.

Sets link name's MTU to mtu.

Renames link name to new_name.

Brings link name administratively up (sets IFF_UP).

Returns whether link is administratively up (has IFF_UP set).

Types

t()

@type t() :: %Linx.Netlink.Rtnl.Link{
  address: term(),
  change: term(),
  family: term(),
  flags: term(),
  index: term(),
  link: term(),
  linkinfo: term(),
  master: term(),
  mtu: term(),
  name: term(),
  net_ns_pid: term(),
  type: term()
}

Functions

create_bridge(socket, name)

@spec create_bridge(Linx.Netlink.Socket.t(), binary()) :: :ok | {:error, term()}

Creates an empty Linux bridge named name.

create_dummy(socket, name)

@spec create_dummy(Linx.Netlink.Socket.t(), binary()) :: :ok | {:error, term()}

Creates a dummy interface named name — a loopback-like virtual link with no real packet path, useful as a stable address holder or a test fixture.

create_ipvlan(socket, name, parent, mode \\ :l3)

@spec create_ipvlan(Linx.Netlink.Socket.t(), binary(), binary(), :l2 | :l3) ::
  :ok | {:error, term()}

Creates an ipvlan link named name on parent interface parent.

mode is :l3 (default) or :l2.

create_macvlan(socket, name, parent, mode \\ :bridge)

@spec create_macvlan(Linx.Netlink.Socket.t(), binary(), binary(), :bridge | :private) ::
  :ok | {:error, term()}

Creates a macvlan link named name on parent interface parent.

mode is :bridge (default) or :private.

create_veth(socket, name, peer_name)

@spec create_veth(Linx.Netlink.Socket.t(), binary(), binary()) ::
  :ok | {:error, term()}

Creates a veth pair — two interfaces named name and peer_name, connected back-to-back.

create_vlan(socket, name, parent, vlan_id)

@spec create_vlan(Linx.Netlink.Socket.t(), binary(), binary(), 1..4094) ::
  :ok | {:error, term()}

Creates an vlan sub-interface named name on parent parent carrying 802.1Q VLAN tag vlan_id (1..4094).

decode(body)

@spec decode(binary()) :: t()

Decodes a netlink message body into a t/0.

delete(socket, name)

@spec delete(Linx.Netlink.Socket.t(), binary()) :: :ok | {:error, term()}

Deletes the link named name.

encode(message)

@spec encode(t()) :: binary()

Encodes a t/0 into its netlink message body.

get(socket, name)

@spec get(Linx.Netlink.Socket.t(), binary()) :: {:ok, t()} | {:error, term()}

Gets the link named name.

Returns {:error, %Linx.Netlink.Error{errno: :enodev}} if there is no such interface.

list(socket)

@spec list(Linx.Netlink.Socket.t()) :: {:ok, [t()]} | {:error, term()}

Lists every link in the socket's network namespace.

move_to_netns(socket, name, pid)

@spec move_to_netns(Linx.Netlink.Socket.t(), binary(), pos_integer()) ::
  :ok | {:error, term()}

Moves link name into the network namespace of process pid.

set_address(socket, name, mac)

@spec set_address(Linx.Netlink.Socket.t(), binary(), binary() | Linx.MAC.t()) ::
  :ok | {:error, term()}

Sets link name's MAC address to mac — a colon-separated hex string, e.g. "aa:bb:cc:dd:ee:ff", or a Linx.MAC.

set_down(socket, name)

@spec set_down(Linx.Netlink.Socket.t(), binary()) :: :ok | {:error, term()}

Brings link name administratively down (clears IFF_UP).

set_master(socket, name, master_name)

@spec set_master(Linx.Netlink.Socket.t(), binary(), binary()) ::
  :ok | {:error, term()}

Enslaves link name to master_name — typically a bridge or bond.

set_mtu(socket, name, mtu)

@spec set_mtu(Linx.Netlink.Socket.t(), binary(), pos_integer()) ::
  :ok | {:error, term()}

Sets link name's MTU to mtu.

set_name(socket, name, new_name)

@spec set_name(Linx.Netlink.Socket.t(), binary(), binary()) :: :ok | {:error, term()}

Renames link name to new_name.

set_up(socket, name)

@spec set_up(Linx.Netlink.Socket.t(), binary()) :: :ok | {:error, term()}

Brings link name administratively up (sets IFF_UP).

up?(link)

@spec up?(t()) :: boolean()

Returns whether link is administratively up (has IFF_UP set).