1 package netlink
2
3 import (
4 "fmt"
5
6 "github.com/vishvananda/netlink/nl"
7 "golang.org/x/sys/unix"
8 )
9
10
11
12 func BridgeVlanList() (map[int32][]*nl.BridgeVlanInfo, error) {
13 return pkgHandle.BridgeVlanList()
14 }
15
16
17
18 func (h *Handle) BridgeVlanList() (map[int32][]*nl.BridgeVlanInfo, error) {
19 req := h.newNetlinkRequest(unix.RTM_GETLINK, unix.NLM_F_DUMP)
20 msg := nl.NewIfInfomsg(unix.AF_BRIDGE)
21 req.AddData(msg)
22 req.AddData(nl.NewRtAttr(unix.IFLA_EXT_MASK, nl.Uint32Attr(uint32(nl.RTEXT_FILTER_BRVLAN))))
23
24 msgs, err := req.Execute(unix.NETLINK_ROUTE, unix.RTM_NEWLINK)
25 if err != nil {
26 return nil, err
27 }
28 ret := make(map[int32][]*nl.BridgeVlanInfo)
29 for _, m := range msgs {
30 msg := nl.DeserializeIfInfomsg(m)
31
32 attrs, err := nl.ParseRouteAttr(m[msg.Len():])
33 if err != nil {
34 return nil, err
35 }
36 for _, attr := range attrs {
37 switch attr.Attr.Type {
38 case unix.IFLA_AF_SPEC:
39
40 nestAttrs, err := nl.ParseRouteAttr(attr.Value)
41 if err != nil {
42 return nil, fmt.Errorf("failed to parse nested attr %v", err)
43 }
44 for _, nestAttr := range nestAttrs {
45 switch nestAttr.Attr.Type {
46 case nl.IFLA_BRIDGE_VLAN_INFO:
47 vlanInfo := nl.DeserializeBridgeVlanInfo(nestAttr.Value)
48 ret[msg.Index] = append(ret[msg.Index], vlanInfo)
49 }
50 }
51 }
52 }
53 }
54 return ret, nil
55 }
56
57
58
59 func BridgeVlanAdd(link Link, vid uint16, pvid, untagged, self, master bool) error {
60 return pkgHandle.BridgeVlanAdd(link, vid, pvid, untagged, self, master)
61 }
62
63
64
65 func (h *Handle) BridgeVlanAdd(link Link, vid uint16, pvid, untagged, self, master bool) error {
66 return h.bridgeVlanModify(unix.RTM_SETLINK, link, vid, 0, pvid, untagged, self, master)
67 }
68
69
70
71 func BridgeVlanAddRange(link Link, vid, vidEnd uint16, pvid, untagged, self, master bool) error {
72 return pkgHandle.BridgeVlanAddRange(link, vid, vidEnd, pvid, untagged, self, master)
73 }
74
75
76
77 func (h *Handle) BridgeVlanAddRange(link Link, vid, vidEnd uint16, pvid, untagged, self, master bool) error {
78 return h.bridgeVlanModify(unix.RTM_SETLINK, link, vid, vidEnd, pvid, untagged, self, master)
79 }
80
81
82
83 func BridgeVlanDel(link Link, vid uint16, pvid, untagged, self, master bool) error {
84 return pkgHandle.BridgeVlanDel(link, vid, pvid, untagged, self, master)
85 }
86
87
88
89 func (h *Handle) BridgeVlanDel(link Link, vid uint16, pvid, untagged, self, master bool) error {
90 return h.bridgeVlanModify(unix.RTM_DELLINK, link, vid, 0, pvid, untagged, self, master)
91 }
92
93
94
95 func BridgeVlanDelRange(link Link, vid, vidEnd uint16, pvid, untagged, self, master bool) error {
96 return pkgHandle.BridgeVlanDelRange(link, vid, vidEnd, pvid, untagged, self, master)
97 }
98
99
100
101 func (h *Handle) BridgeVlanDelRange(link Link, vid, vidEnd uint16, pvid, untagged, self, master bool) error {
102 return h.bridgeVlanModify(unix.RTM_DELLINK, link, vid, vidEnd, pvid, untagged, self, master)
103 }
104
105 func (h *Handle) bridgeVlanModify(cmd int, link Link, vid, vidEnd uint16, pvid, untagged, self, master bool) error {
106 base := link.Attrs()
107 h.ensureIndex(base)
108 req := h.newNetlinkRequest(cmd, unix.NLM_F_ACK)
109
110 msg := nl.NewIfInfomsg(unix.AF_BRIDGE)
111 msg.Index = int32(base.Index)
112 req.AddData(msg)
113
114 br := nl.NewRtAttr(unix.IFLA_AF_SPEC, nil)
115 var flags uint16
116 if self {
117 flags |= nl.BRIDGE_FLAGS_SELF
118 }
119 if master {
120 flags |= nl.BRIDGE_FLAGS_MASTER
121 }
122 if flags > 0 {
123 br.AddRtAttr(nl.IFLA_BRIDGE_FLAGS, nl.Uint16Attr(flags))
124 }
125 vlanInfo := &nl.BridgeVlanInfo{Vid: vid}
126 if pvid {
127 vlanInfo.Flags |= nl.BRIDGE_VLAN_INFO_PVID
128 }
129 if untagged {
130 vlanInfo.Flags |= nl.BRIDGE_VLAN_INFO_UNTAGGED
131 }
132
133 if vidEnd != 0 {
134 vlanEndInfo := &nl.BridgeVlanInfo{Vid: vidEnd}
135 vlanEndInfo.Flags = vlanInfo.Flags
136
137 vlanInfo.Flags |= nl.BRIDGE_VLAN_INFO_RANGE_BEGIN
138 br.AddRtAttr(nl.IFLA_BRIDGE_VLAN_INFO, vlanInfo.Serialize())
139
140 vlanEndInfo.Flags |= nl.BRIDGE_VLAN_INFO_RANGE_END
141 br.AddRtAttr(nl.IFLA_BRIDGE_VLAN_INFO, vlanEndInfo.Serialize())
142 } else {
143 br.AddRtAttr(nl.IFLA_BRIDGE_VLAN_INFO, vlanInfo.Serialize())
144 }
145
146 req.AddData(br)
147 _, err := req.Execute(unix.NETLINK_ROUTE, 0)
148 return err
149 }
150
View as plain text