github.com/vishvananda/netlink@v1.3.0/chain_linux.go (about)

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