github.com/vishvananda/netlink@v1.3.1/chain_linux.go (about) 1 package netlink 2 3 import ( 4 "errors" 5 6 "github.com/vishvananda/netlink/nl" 7 "golang.org/x/sys/unix" 8 ) 9 10 // ChainDel will delete a chain from the system. 11 func ChainDel(link Link, chain Chain) error { 12 // Equivalent to: `tc chain del $chain` 13 return pkgHandle.ChainDel(link, chain) 14 } 15 16 // ChainDel will delete a chain from the system. 17 // Equivalent to: `tc chain del $chain` 18 func (h *Handle) ChainDel(link Link, chain Chain) error { 19 return h.chainModify(unix.RTM_DELCHAIN, 0, link, chain) 20 } 21 22 // ChainAdd will add a chain to the system. 23 // Equivalent to: `tc chain add` 24 func ChainAdd(link Link, chain Chain) error { 25 return pkgHandle.ChainAdd(link, chain) 26 } 27 28 // ChainAdd will add a chain to the system. 29 // Equivalent to: `tc chain add` 30 func (h *Handle) ChainAdd(link Link, chain Chain) error { 31 return h.chainModify( 32 unix.RTM_NEWCHAIN, 33 unix.NLM_F_CREATE|unix.NLM_F_EXCL, 34 link, 35 chain) 36 } 37 38 func (h *Handle) chainModify(cmd, flags int, link Link, chain Chain) error { 39 req := h.newNetlinkRequest(cmd, flags|unix.NLM_F_ACK) 40 index := int32(0) 41 if link != nil { 42 base := link.Attrs() 43 h.ensureIndex(base) 44 index = int32(base.Index) 45 } 46 msg := &nl.TcMsg{ 47 Family: nl.FAMILY_ALL, 48 Ifindex: index, 49 Parent: chain.Parent, 50 } 51 req.AddData(msg) 52 req.AddData(nl.NewRtAttr(nl.TCA_CHAIN, nl.Uint32Attr(chain.Chain))) 53 54 _, err := req.Execute(unix.NETLINK_ROUTE, 0) 55 return err 56 } 57 58 // ChainList gets a list of chains in the system. 59 // Equivalent to: `tc chain list`. 60 // The list can be filtered by link. 61 // 62 // If the returned error is [ErrDumpInterrupted], results may be inconsistent 63 // or incomplete. 64 func ChainList(link Link, parent uint32) ([]Chain, error) { 65 return pkgHandle.ChainList(link, parent) 66 } 67 68 // ChainList gets a list of chains in the system. 69 // Equivalent to: `tc chain list`. 70 // The list can be filtered by link. 71 // 72 // If the returned error is [ErrDumpInterrupted], results may be inconsistent 73 // or incomplete. 74 func (h *Handle) ChainList(link Link, parent uint32) ([]Chain, error) { 75 req := h.newNetlinkRequest(unix.RTM_GETCHAIN, unix.NLM_F_DUMP) 76 index := int32(0) 77 if link != nil { 78 base := link.Attrs() 79 h.ensureIndex(base) 80 index = int32(base.Index) 81 } 82 msg := &nl.TcMsg{ 83 Family: nl.FAMILY_ALL, 84 Ifindex: index, 85 Parent: parent, 86 } 87 req.AddData(msg) 88 89 msgs, executeErr := req.Execute(unix.NETLINK_ROUTE, unix.RTM_NEWCHAIN) 90 if executeErr != nil && !errors.Is(executeErr, ErrDumpInterrupted) { 91 return nil, executeErr 92 } 93 94 var res []Chain 95 for _, m := range msgs { 96 msg := nl.DeserializeTcMsg(m) 97 98 attrs, err := nl.ParseRouteAttr(m[msg.Len():]) 99 if err != nil { 100 return nil, err 101 } 102 103 // skip chains from other interfaces 104 if link != nil && msg.Ifindex != index { 105 continue 106 } 107 108 var chain Chain 109 for _, attr := range attrs { 110 switch attr.Attr.Type { 111 case nl.TCA_CHAIN: 112 chain.Chain = native.Uint32(attr.Value) 113 chain.Parent = parent 114 } 115 } 116 res = append(res, chain) 117 } 118 119 return res, executeErr 120 }