Line data Source code
1 : /* SPDX-License-Identifier: LGPL-2.1+ */
2 :
3 : #include <net/if.h>
4 :
5 : #include "conf-parser.h"
6 : #include "netdev/ipvlan.h"
7 : #include "networkd-link.h"
8 : #include "string-table.h"
9 :
10 : static const char* const ipvlan_mode_table[_NETDEV_IPVLAN_MODE_MAX] = {
11 : [NETDEV_IPVLAN_MODE_L2] = "L2",
12 : [NETDEV_IPVLAN_MODE_L3] = "L3",
13 : [NETDEV_IPVLAN_MODE_L3S] = "L3S",
14 : };
15 :
16 10 : DEFINE_STRING_TABLE_LOOKUP(ipvlan_mode, IPVlanMode);
17 0 : DEFINE_CONFIG_PARSE_ENUM(config_parse_ipvlan_mode, ipvlan_mode, IPVlanMode, "Failed to parse ipvlan mode");
18 :
19 : static const char* const ipvlan_flags_table[_NETDEV_IPVLAN_FLAGS_MAX] = {
20 : [NETDEV_IPVLAN_FLAGS_BRIGDE] = "bridge",
21 : [NETDEV_IPVLAN_FLAGS_PRIVATE] = "private",
22 : [NETDEV_IPVLAN_FLAGS_VEPA] = "vepa",
23 : };
24 :
25 10 : DEFINE_STRING_TABLE_LOOKUP(ipvlan_flags, IPVlanFlags);
26 0 : DEFINE_CONFIG_PARSE_ENUM(config_parse_ipvlan_flags, ipvlan_flags, IPVlanFlags, "Failed to parse ipvlan flags");
27 :
28 0 : static int netdev_ipvlan_fill_message_create(NetDev *netdev, Link *link, sd_netlink_message *req) {
29 : IPVlan *m;
30 : int r;
31 :
32 0 : assert(netdev);
33 0 : assert(link);
34 0 : assert(netdev->ifname);
35 :
36 0 : if (netdev->kind == NETDEV_KIND_IPVLAN)
37 0 : m = IPVLAN(netdev);
38 : else
39 0 : m = IPVTAP(netdev);
40 :
41 0 : assert(m);
42 :
43 0 : if (m->mode != _NETDEV_IPVLAN_MODE_INVALID) {
44 0 : r = sd_netlink_message_append_u16(req, IFLA_IPVLAN_MODE, m->mode);
45 0 : if (r < 0)
46 0 : return log_netdev_error_errno(netdev, r, "Could not append IFLA_IPVLAN_MODE attribute: %m");
47 : }
48 :
49 0 : if (m->flags != _NETDEV_IPVLAN_FLAGS_INVALID) {
50 0 : r = sd_netlink_message_append_u16(req, IFLA_IPVLAN_FLAGS, m->flags);
51 0 : if (r < 0)
52 0 : return log_netdev_error_errno(netdev, r, "Could not append IFLA_IPVLAN_FLAGS attribute: %m");
53 : }
54 :
55 0 : return 0;
56 : }
57 :
58 0 : static void ipvlan_init(NetDev *n) {
59 : IPVlan *m;
60 :
61 0 : assert(n);
62 :
63 0 : if (n->kind == NETDEV_KIND_IPVLAN)
64 0 : m = IPVLAN(n);
65 : else
66 0 : m = IPVTAP(n);
67 :
68 0 : assert(m);
69 :
70 0 : m->mode = _NETDEV_IPVLAN_MODE_INVALID;
71 0 : m->flags = _NETDEV_IPVLAN_FLAGS_INVALID;
72 0 : }
73 :
74 : const NetDevVTable ipvlan_vtable = {
75 : .object_size = sizeof(IPVlan),
76 : .init = ipvlan_init,
77 : .sections = "Match\0NetDev\0IPVLAN\0",
78 : .fill_message_create = netdev_ipvlan_fill_message_create,
79 : .create_type = NETDEV_CREATE_STACKED,
80 : .generate_mac = true,
81 : };
82 :
83 : const NetDevVTable ipvtap_vtable = {
84 : .object_size = sizeof(IPVlan),
85 : .init = ipvlan_init,
86 : .sections = "Match\0NetDev\0IPVTAP\0",
87 : .fill_message_create = netdev_ipvlan_fill_message_create,
88 : .create_type = NETDEV_CREATE_STACKED,
89 : .generate_mac = true,
90 : };
91 :
92 0 : IPVlanMode link_get_ipvlan_mode(Link *link) {
93 : NetDev *netdev;
94 :
95 0 : if (!streq_ptr(link->kind, "ipvlan"))
96 0 : return _NETDEV_IPVLAN_MODE_INVALID;
97 :
98 0 : if (netdev_get(link->manager, link->ifname, &netdev) < 0)
99 0 : return _NETDEV_IPVLAN_MODE_INVALID;
100 :
101 0 : if (netdev->kind != NETDEV_KIND_IPVLAN)
102 0 : return _NETDEV_IPVLAN_MODE_INVALID;
103 :
104 0 : return IPVLAN(netdev)->mode;
105 : }
|