Support invert in ip rules

Signed-off-by: Alessandro Boch <aboch@tetrationanalytics.com>
This commit is contained in:
Alessandro Boch 2017-11-07 09:34:56 -08:00 committed by Vish (Ishaya) Abrams
parent ae21927b7c
commit 6174cd873f
3 changed files with 25 additions and 10 deletions

View File

@ -21,6 +21,7 @@ type Rule struct {
OifName string
SuppressIfgroup int
SuppressPrefixlen int
Invert bool
}
func (r Rule) String() string {

View File

@ -8,6 +8,8 @@ import (
"golang.org/x/sys/unix"
)
const FibRuleInvert = 0x2
// RuleAdd adds a rule to the system.
// Equivalent to: ip rule add
func RuleAdd(rule *Rule) error {
@ -30,18 +32,31 @@ func RuleDel(rule *Rule) error {
// RuleDel deletes a rule from the system.
// Equivalent to: ip rule del
func (h *Handle) RuleDel(rule *Rule) error {
req := h.newNetlinkRequest(unix.RTM_DELRULE, unix.NLM_F_CREATE|unix.NLM_F_EXCL|unix.NLM_F_ACK)
req := h.newNetlinkRequest(unix.RTM_DELRULE, unix.NLM_F_ACK)
return ruleHandle(rule, req)
}
func ruleHandle(rule *Rule, req *nl.NetlinkRequest) error {
msg := nl.NewRtMsg()
msg.Family = unix.AF_INET
msg.Protocol = unix.RTPROT_BOOT
msg.Scope = unix.RT_SCOPE_UNIVERSE
msg.Table = unix.RT_TABLE_UNSPEC
msg.Type = unix.RTN_UNSPEC
if req.NlMsghdr.Flags&unix.NLM_F_CREATE > 0 {
msg.Type = unix.RTN_UNICAST
}
if rule.Invert {
msg.Flags |= FibRuleInvert
}
if rule.Family != 0 {
msg.Family = uint8(rule.Family)
}
var dstFamily uint8
if rule.Table >= 0 && rule.Table < 256 {
msg.Table = uint8(rule.Table)
}
var dstFamily uint8
var rtAttrs []*nl.RtAttr
if rule.Dst != nil && rule.Dst.IP != nil {
dstLen, _ := rule.Dst.Mask.Size()
@ -73,13 +88,6 @@ func ruleHandle(rule *Rule, req *nl.NetlinkRequest) error {
rtAttrs = append(rtAttrs, nl.NewRtAttr(unix.RTA_SRC, srcData))
}
if rule.Table >= 0 {
msg.Table = uint8(rule.Table)
if rule.Table >= 256 {
msg.Table = unix.RT_TABLE_UNSPEC
}
}
req.AddData(msg)
for i := range rtAttrs {
req.AddData(rtAttrs[i])
@ -175,6 +183,8 @@ func (h *Handle) RuleList(family int) ([]Rule, error) {
rule := NewRule()
rule.Invert = msg.Flags&FibRuleInvert > 0
for j := range attrs {
switch attrs[j].Attr.Type {
case unix.RTA_TABLE:

View File

@ -11,6 +11,7 @@ import (
func TestRuleAddDel(t *testing.T) {
skipUnlessRoot(t)
setUpNetlinkTest(t)()
srcNet := &net.IPNet{IP: net.IPv4(172, 16, 0, 1), Mask: net.CIDRMask(16, 32)}
dstNet := &net.IPNet{IP: net.IPv4(172, 16, 1, 1), Mask: net.CIDRMask(24, 32)}
@ -27,6 +28,7 @@ func TestRuleAddDel(t *testing.T) {
rule.Priority = 5
rule.OifName = "lo"
rule.IifName = "lo"
rule.Invert = true
if err := RuleAdd(rule); err != nil {
t.Fatal(err)
}
@ -48,8 +50,10 @@ func TestRuleAddDel(t *testing.T) {
rules[i].Dst != nil && rules[i].Dst.String() == dstNet.String() &&
rules[i].OifName == rule.OifName &&
rules[i].Priority == rule.Priority &&
rules[i].IifName == rule.IifName {
rules[i].IifName == rule.IifName &&
rules[i].Invert == rule.Invert {
found = true
break
}
}
if !found {