diff --git a/go/pkg/pass1/cut-netspoc.go b/go/pkg/pass1/cut-netspoc.go index 3f9b52f2..d0d729cb 100644 --- a/go/pkg/pass1/cut-netspoc.go +++ b/go/pkg/pass1/cut-netspoc.go @@ -316,6 +316,7 @@ func (c *spoc) markAndSubstElements( typ, name, _ := strings.Cut(name, ":") switch x := obj.(type) { case *host, *area: + isUsed[name] = true a := new(ast.NamedRef) a.Type = typ a.Name = name @@ -332,18 +333,37 @@ func (c *spoc) markAndSubstElements( a := new(ast.AggAuto) a.Type = typ a.Net = ip - n := new(ast.NamedRef) - n.Type = "network" - n.Name = name[len("network:"):] - a.Elements = []ast.Element{n} + switch typ2, name2, _ := strings.Cut(name, ":"); typ2 { + case "network": + obj := c.symTable.network[name2] + markUnconnectedObj(obj, isUsed) + n := new(ast.NamedRef) + n.Type = typ2 + n.Name = name2 + a.Elements = []ast.Element{n} + case "interface": + isUsed[name] = true + r, net, _ := strings.Cut(name2, ".") + n := new(ast.IntfRef) + n.Type = typ2 + n.Router = r + if left, right, found := strings.Cut(net, "."); found { + net = left + n.Extension = right + } + n.Network = net + a.Elements = []ast.Element{n} + } result = a } else { + markUnconnectedObj(x, isUsed) a := new(ast.NamedRef) a.Type = typ a.Name = name result = a } case *routerIntf: + setIntfUsed(x, isUsed) r, net, _ := strings.Cut(name, ".") a := new(ast.IntfRef) a.Type = typ @@ -356,6 +376,7 @@ func (c *spoc) markAndSubstElements( result = a case *autoIntf: if r, ok := x.object.(*router); ok { + setRouterUsed(r, isUsed) a := new(ast.IntfRef) a.Type = typ a.Router = r.name[len("router:"):] @@ -364,6 +385,7 @@ func (c *spoc) markAndSubstElements( result = a } else { net := x.object.(*network) + markUnconnectedObj(net, isUsed) a := new(ast.IntfAuto) a.Type = typ a.Managed = x.managed @@ -406,14 +428,14 @@ func (c *spoc) markAndSubstElements( } // Remove sub elements that would evaluate to empty list. l2 := traverse(x.GetElements()) - var l3 []ast.Element + j2 := 0 for _, el2 := range l2 { - x.SetElements([]ast.Element{el2}) - if len(expand(el)) != 0 { - l3 = append(l3, el2) + if len(expand(el2)) != 0 { + l2[j2] = el2 + j2++ } } - x.SetElements(l3) + x.SetElements(l2[:j2]) case *ast.IntfRef: for _, obj := range expand(el) { switch x := obj.(type) { diff --git a/go/testdata/cut-netspoc/cut-netspoc.t b/go/testdata/cut-netspoc/cut-netspoc.t index 0fd74f40..43c77b0d 100644 --- a/go/testdata/cut-netspoc/cut-netspoc.t +++ b/go/testdata/cut-netspoc/cut-netspoc.t @@ -990,12 +990,14 @@ service:test = { } =OUTPUT= network:n1 = { ip = 10.1.1.0/24; } +network:n2 = { ip = 10.1.2.0/24; } network:n3 = { ip = 10.1.3.0/24; } network:n4 = { ip = 10.1.4.0/24; } router:r1 = { managed; model = ASA; interface:n1 = { ip = 10.1.1.1; hardware = n1; } + interface:n2 = { ip = 10.1.2.1; hardware = n2; } interface:n3 = { ip = 10.1.3.1; hardware = n3; } } router:r2 = { @@ -1007,6 +1009,7 @@ router:r2 = { service:test = { user = network:[ any:[ip = 10.1.0.0/23 & network:n1], + any:[ip = 10.1.0.0/23 & network:n2], ], network:n3, ; @@ -3222,6 +3225,70 @@ service:s1 = { [[input]] =SUBST=/group:g1 &! network:n1 &! network:n2/network:n3/ +############################################################ +=TITLE=Intersection of nested elements of different type +=TEMPL=input +service:s1 = { + user = group:g1; + permit src = user; + dst = network:n1; + prt = tcp 80; +} +network:n1 = { ip = 10.1.1.0/24; } +router:r2 = { + model = ASA; + managed; + interface:n1 = { ip = 10.1.1.4; hardware = n1; } + interface:n2 = { + ip = 10.1.2.1; + hardware = n2; + hub = crypto:s2s; + } +} +network:n2 = { ip = 10.1.2.0/24; } +router:r3 = { + interface:n2 = { + ip = 10.1.2.2; + spoke = crypto:s2s; + } + interface:lo = { ip = 10.9.9.13; loopback; }{{.}} +} +crypto:s2s = { + type = ipsec:s2s; +} +ipsec:s2s = { + key_exchange = isakmp:s2s; + esp_encryption = aes256; + esp_authentication = sha256; + lifetime = 3600 sec 102400 kilobytes; +} +isakmp:s2s = { + ike_version = 2; + authentication = preshare; + encryption = aes256; + hash = sha256; + group = 19; + lifetime = 28800 sec; +} +=INPUT= +group:g1 = + any:[ip = 10.9.9.0/24 & + any:[interface:r3.[all]] &! any:[network:n2] + ], +; +[[input "\n interface:n3 = { ip = 10.1.3.1; }"]] +network:n3 = { ip = 10.1.3.0/24; } +=OUTPUT= +group:g1 = + any:[ip = 10.9.9.0/24 & + any:[ + interface:r3.lo, + ], + ], +; +[[input ""]] +=END= + ############################################################ =TITLE=Network auto interface =TEMPL=input