catch interface up/down
This commit is contained in:
parent
319e75fd15
commit
1015423a8f
@ -10,7 +10,7 @@ Realized features:
|
|||||||
- [X] IPSet integration
|
- [X] IPSet integration
|
||||||
- [X] IP integration
|
- [X] IP integration
|
||||||
- [X] IPTables rules to IPSet
|
- [X] IPTables rules to IPSet
|
||||||
- [ ] Catch interface up/down
|
- [X] Catch interface up/down
|
||||||
- [ ] Catch `netfilter.d` event
|
- [ ] Catch `netfilter.d` event
|
||||||
- [ ] Rule composer (CRUD)
|
- [ ] Rule composer (CRUD)
|
||||||
- [ ] GORM integration
|
- [ ] GORM integration
|
||||||
|
50
kvas2.go
50
kvas2.go
@ -13,6 +13,7 @@ import (
|
|||||||
"kvas2-go/netfilter-helper"
|
"kvas2-go/netfilter-helper"
|
||||||
|
|
||||||
"github.com/rs/zerolog/log"
|
"github.com/rs/zerolog/log"
|
||||||
|
"github.com/vishvananda/netlink"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -98,11 +99,54 @@ func (a *App) Listen(ctx context.Context) []error {
|
|||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
select {
|
link := make(chan netlink.LinkUpdate)
|
||||||
case <-ctx.Done():
|
done := make(chan struct{})
|
||||||
case <-isError:
|
netlink.LinkSubscribe(link, done)
|
||||||
|
|
||||||
|
Loop:
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case event := <-link:
|
||||||
|
switch event.Change {
|
||||||
|
case 0x00000001:
|
||||||
|
log.Debug().
|
||||||
|
Str("interface", event.Link.Attrs().Name).
|
||||||
|
Str("operstatestr", event.Attrs().OperState.String()).
|
||||||
|
Int("operstate", int(event.Attrs().OperState)).
|
||||||
|
Msg("interface change")
|
||||||
|
if event.Attrs().OperState != netlink.OperDown {
|
||||||
|
for _, group := range a.Groups {
|
||||||
|
if group.Interface == event.Link.Attrs().Name {
|
||||||
|
err = group.ifaceToIPSet.IfaceHandle()
|
||||||
|
if err != nil {
|
||||||
|
log.Error().Int("group", group.ID).Err(err).Msg("error while handling interface up")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case 0xFFFFFFFF:
|
||||||
|
switch event.Header.Type {
|
||||||
|
case 16:
|
||||||
|
log.Debug().
|
||||||
|
Str("interface", event.Link.Attrs().Name).
|
||||||
|
Int("type", int(event.Header.Type)).
|
||||||
|
Msg("interface add")
|
||||||
|
case 17:
|
||||||
|
log.Debug().
|
||||||
|
Str("interface", event.Link.Attrs().Name).
|
||||||
|
Int("type", int(event.Header.Type)).
|
||||||
|
Msg("interface del")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case <-ctx.Done():
|
||||||
|
break Loop
|
||||||
|
case <-isError:
|
||||||
|
break Loop
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
close(done)
|
||||||
|
|
||||||
errs2 := a.dnsOverrider.Disable()
|
errs2 := a.dnsOverrider.Disable()
|
||||||
if errs2 != nil {
|
if errs2 != nil {
|
||||||
handleErrors(errs2)
|
handleErrors(errs2)
|
||||||
|
@ -25,18 +25,41 @@ type IfaceToIPSet struct {
|
|||||||
ipRoute *netlink.Route
|
ipRoute *netlink.Route
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *IfaceToIPSet) IfaceHandle() error {
|
||||||
|
// Find interface
|
||||||
|
iface, err := netlink.LinkByName(r.IfaceName)
|
||||||
|
if err != nil {
|
||||||
|
log.Warn().Str("interface", r.IfaceName).Err(err).Msg("error while getting interface")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mapping iface with table
|
||||||
|
if iface != nil {
|
||||||
|
route := &netlink.Route{
|
||||||
|
LinkIndex: iface.Attrs().Index,
|
||||||
|
Table: r.table,
|
||||||
|
Dst: &net.IPNet{IP: []byte{0, 0, 0, 0}, Mask: []byte{0, 0, 0, 0}},
|
||||||
|
}
|
||||||
|
// Delete rule if exists
|
||||||
|
err = netlink.RouteDel(route)
|
||||||
|
if err != nil {
|
||||||
|
log.Warn().Str("interface", r.IfaceName).Err(err).Msg("error while deleting route")
|
||||||
|
}
|
||||||
|
err = netlink.RouteAdd(route)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("error while mapping iface with table: %w", err)
|
||||||
|
}
|
||||||
|
r.ipRoute = route
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (r *IfaceToIPSet) ForceEnable() error {
|
func (r *IfaceToIPSet) ForceEnable() error {
|
||||||
// Release used mark and table
|
// Release used mark and table
|
||||||
r.Disable()
|
r.Disable()
|
||||||
r.mark = 0
|
r.mark = 0
|
||||||
r.table = 0
|
r.table = 0
|
||||||
|
|
||||||
// Find interface
|
|
||||||
iface, err := netlink.LinkByName(r.IfaceName)
|
|
||||||
if err != nil {
|
|
||||||
log.Warn().Str("interface", r.IfaceName).Msg("error while getting interface")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Find unused mark and table
|
// Find unused mark and table
|
||||||
markMap := make(map[uint32]struct{})
|
markMap := make(map[uint32]struct{})
|
||||||
tableMap := map[int]struct{}{0: {}, 253: {}, 254: {}, 255: {}}
|
tableMap := map[int]struct{}{0: {}, 253: {}, 254: {}, 255: {}}
|
||||||
@ -152,18 +175,9 @@ func (r *IfaceToIPSet) ForceEnable() error {
|
|||||||
}
|
}
|
||||||
r.ipRule = rule
|
r.ipRule = rule
|
||||||
|
|
||||||
// Mapping iface with table
|
err = r.IfaceHandle()
|
||||||
if iface != nil {
|
if err != nil {
|
||||||
route := &netlink.Route{
|
return nil
|
||||||
LinkIndex: iface.Attrs().Index,
|
|
||||||
Table: rule.Table,
|
|
||||||
Dst: &net.IPNet{IP: []byte{0, 0, 0, 0}, Mask: []byte{0, 0, 0, 0}},
|
|
||||||
}
|
|
||||||
err = netlink.RouteAdd(route)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("error while mapping iface with table: %w", err)
|
|
||||||
}
|
|
||||||
r.ipRoute = route
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
Loading…
x
Reference in New Issue
Block a user