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  }