]>
Commit | Line | Data |
---|---|---|
53e1b683 | 1 | /* SPDX-License-Identifier: LGPL-2.1+ */ |
0372cb2b | 2 | /*** |
96b2fb93 | 3 | Copyright © 2013 Tom Gundersen <teg@jklm.no> |
0372cb2b TG |
4 | ***/ |
5 | ||
dccca82b | 6 | #include <errno.h> |
c8b21184 | 7 | #include <linux/if_vlan.h> |
0372cb2b TG |
8 | #include <net/if.h> |
9 | ||
441e9ae4 | 10 | #include "netdev/vlan.h" |
267fabd2 | 11 | #include "vlan-util.h" |
0372cb2b | 12 | |
1c4baffc | 13 | static int netdev_vlan_fill_message_create(NetDev *netdev, Link *link, sd_netlink_message *req) { |
c8b21184 | 14 | struct ifla_vlan_flags flags = {}; |
2645f07d | 15 | VLan *v; |
0372cb2b TG |
16 | int r; |
17 | ||
18 | assert(netdev); | |
0372cb2b | 19 | assert(link); |
3be1d7e0 | 20 | assert(req); |
0372cb2b | 21 | |
2645f07d SS |
22 | v = VLAN(netdev); |
23 | ||
24 | assert(v); | |
25 | ||
267fabd2 LP |
26 | r = sd_netlink_message_append_u16(req, IFLA_VLAN_ID, v->id); |
27 | if (r < 0) | |
28 | return log_netdev_error_errno(netdev, r, "Could not append IFLA_VLAN_ID attribute: %m"); | |
0372cb2b | 29 | |
c8b21184 SS |
30 | if (v->gvrp != -1) { |
31 | flags.mask |= VLAN_FLAG_GVRP; | |
ab8ee0f2 | 32 | SET_FLAG(flags.flags, VLAN_FLAG_GVRP, v->gvrp); |
c8b21184 SS |
33 | } |
34 | ||
6c1ff21b SS |
35 | if (v->mvrp != -1) { |
36 | flags.mask |= VLAN_FLAG_MVRP; | |
37 | SET_FLAG(flags.flags, VLAN_FLAG_MVRP, v->mvrp); | |
38 | } | |
39 | ||
40 | if (v->reorder_hdr != -1) { | |
41 | flags.mask |= VLAN_FLAG_REORDER_HDR; | |
42 | SET_FLAG(flags.flags, VLAN_FLAG_REORDER_HDR, v->reorder_hdr); | |
43 | } | |
44 | ||
45 | if (v->loose_binding != -1) { | |
46 | flags.mask |= VLAN_FLAG_LOOSE_BINDING; | |
47 | SET_FLAG(flags.flags, VLAN_FLAG_LOOSE_BINDING, v->loose_binding); | |
48 | } | |
49 | ||
c8b21184 SS |
50 | r = sd_netlink_message_append_data(req, IFLA_VLAN_FLAGS, &flags, sizeof(struct ifla_vlan_flags)); |
51 | if (r < 0) | |
52 | return log_netdev_error_errno(netdev, r, "Could not append IFLA_VLAN_FLAGS attribute: %m"); | |
53 | ||
3be1d7e0 TG |
54 | return 0; |
55 | } | |
e04468de | 56 | |
3be1d7e0 | 57 | static int netdev_vlan_verify(NetDev *netdev, const char *filename) { |
2645f07d | 58 | VLan *v; |
aa9f1140 | 59 | |
3be1d7e0 TG |
60 | assert(netdev); |
61 | assert(filename); | |
0372cb2b | 62 | |
2645f07d SS |
63 | v = VLAN(netdev); |
64 | ||
65 | assert(v); | |
66 | ||
267fabd2 LP |
67 | if (v->id == VLANID_INVALID) { |
68 | log_warning("VLAN without valid Id (%"PRIu16") configured in %s.", v->id, filename); | |
3be1d7e0 TG |
69 | return -EINVAL; |
70 | } | |
0372cb2b TG |
71 | |
72 | return 0; | |
73 | } | |
3be1d7e0 | 74 | |
aa9f1140 TG |
75 | static void vlan_init(NetDev *netdev) { |
76 | VLan *v = VLAN(netdev); | |
77 | ||
78 | assert(netdev); | |
79 | assert(v); | |
80 | ||
267fabd2 | 81 | v->id = VLANID_INVALID; |
c8b21184 | 82 | v->gvrp = -1; |
6c1ff21b SS |
83 | v->mvrp = -1; |
84 | v->loose_binding = -1; | |
85 | v->reorder_hdr = -1; | |
aa9f1140 TG |
86 | } |
87 | ||
3be1d7e0 | 88 | const NetDevVTable vlan_vtable = { |
aa9f1140 TG |
89 | .object_size = sizeof(VLan), |
90 | .init = vlan_init, | |
91 | .sections = "Match\0NetDev\0VLAN\0", | |
92 | .fill_message_create = netdev_vlan_fill_message_create, | |
93 | .create_type = NETDEV_CREATE_STACKED, | |
3be1d7e0 TG |
94 | .config_verify = netdev_vlan_verify, |
95 | }; |