github.com/vishvananda/netlink@v1.3.0/bridge_linux.go (about) 1 package netlink 2 3 import ( 4 "fmt" 5 6 "github.com/vishvananda/netlink/nl" 7 "golang.org/x/sys/unix" 8 ) 9 10 // BridgeVlanList gets a map of device id to bridge vlan infos. 11 // Equivalent to: `bridge vlan show` 12 func BridgeVlanList() (map[int32][]*nl.BridgeVlanInfo, error) { 13 return pkgHandle.BridgeVlanList() 14 } 15 16 // BridgeVlanList gets a map of device id to bridge vlan infos. 17 // Equivalent to: `bridge vlan show` 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 //nested attr 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 // BridgeVlanAdd adds a new vlan filter entry 58 // Equivalent to: `bridge vlan add dev DEV vid VID [ pvid ] [ untagged ] [ self ] [ master ]` 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 // BridgeVlanAdd adds a new vlan filter entry 64 // Equivalent to: `bridge vlan add dev DEV vid VID [ pvid ] [ untagged ] [ self ] [ master ]` 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 // BridgeVlanAddRange adds a new vlan filter entry 70 // Equivalent to: `bridge vlan add dev DEV vid VID-VIDEND [ pvid ] [ untagged ] [ self ] [ master ]` 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 // BridgeVlanAddRange adds a new vlan filter entry 76 // Equivalent to: `bridge vlan add dev DEV vid VID-VIDEND [ pvid ] [ untagged ] [ self ] [ master ]` 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 // BridgeVlanDel adds a new vlan filter entry 82 // Equivalent to: `bridge vlan del dev DEV vid VID [ pvid ] [ untagged ] [ self ] [ master ]` 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 // BridgeVlanDel adds a new vlan filter entry 88 // Equivalent to: `bridge vlan del dev DEV vid VID [ pvid ] [ untagged ] [ self ] [ master ]` 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 // BridgeVlanDelRange adds a new vlan filter entry 94 // Equivalent to: `bridge vlan del dev DEV vid VID-VIDEND [ pvid ] [ untagged ] [ self ] [ master ]` 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 // BridgeVlanDelRange adds a new vlan filter entry 100 // Equivalent to: `bridge vlan del dev DEV vid VID-VIDEND [ pvid ] [ untagged ] [ self ] [ master ]` 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 }