123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899 |
- package netlink
- import (
- "fmt"
- "syscall"
- "github.com/vishvananda/netns"
- "github.com/vishvananda/netlink/nl"
- )
- type XfrmMsg interface {
- Type() nl.XfrmMsgType
- }
- type XfrmMsgExpire struct {
- XfrmState *XfrmState
- Hard bool
- }
- func (ue *XfrmMsgExpire) Type() nl.XfrmMsgType {
- return nl.XFRM_MSG_EXPIRE
- }
- func parseXfrmMsgExpire(b []byte) *XfrmMsgExpire {
- var e XfrmMsgExpire
- msg := nl.DeserializeXfrmUserExpire(b)
- e.XfrmState = xfrmStateFromXfrmUsersaInfo(&msg.XfrmUsersaInfo)
- e.Hard = msg.Hard == 1
- return &e
- }
- func XfrmMonitor(ch chan<- XfrmMsg, done <-chan struct{}, errorChan chan<- error,
- types ...nl.XfrmMsgType) error {
- groups, err := xfrmMcastGroups(types)
- if err != nil {
- return nil
- }
- s, err := nl.SubscribeAt(netns.None(), netns.None(), syscall.NETLINK_XFRM, groups...)
- if err != nil {
- return err
- }
- if done != nil {
- go func() {
- <-done
- s.Close()
- }()
- }
- go func() {
- defer close(ch)
- for {
- msgs, err := s.Receive()
- if err != nil {
- errorChan <- err
- return
- }
- for _, m := range msgs {
- switch m.Header.Type {
- case nl.XFRM_MSG_EXPIRE:
- ch <- parseXfrmMsgExpire(m.Data)
- default:
- errorChan <- fmt.Errorf("unsupported msg type: %x", m.Header.Type)
- }
- }
- }
- }()
- return nil
- }
- func xfrmMcastGroups(types []nl.XfrmMsgType) ([]uint, error) {
- groups := make([]uint, 0)
- if len(types) == 0 {
- return nil, fmt.Errorf("no xfrm msg type specified")
- }
- for _, t := range types {
- var group uint
- switch t {
- case nl.XFRM_MSG_EXPIRE:
- group = nl.XFRMNLGRP_EXPIRE
- default:
- return nil, fmt.Errorf("unsupported group: %x", t)
- }
- groups = append(groups, group)
- }
- return groups, nil
- }
|