Skip to content

Commit 60b748f

Browse files
authored
Subscription callbacks for acl and interface app modules (sonic-net#86)
* Subscription callbacks for acl and interface app modules * Implemented translateSubscribe() and processSubscribe() methods in AclApp and IntfApp. Mapping is based on the existing processGet() implementation. This may not be accurate since both the app modules have not been updated since long time. But it will be useful for testing the subscription feature. * Current IntfApp supports only physcial ports in get/set operations. Same limitation is applicable for subscription as well. * Added utilities for processing the path objects and help prepare the translateSubscribe() resposne. * Added gotest helper functions to call translateSubscribe() and verify the responses. Added gotest cases to verify different openconfig-acl and openconfig-interfaces yang paths. * Fixed incorrect paths & payloads used by the existing AclApp get/set test cases. Signed-off-by: Sachin Holla <[email protected]> * Init test data for ACL gotests * Minor cleanups to address review comments * Define constants for port related table names --------- Signed-off-by: Sachin Holla <[email protected]>
1 parent cf40f46 commit 60b748f

File tree

13 files changed

+1801
-100
lines changed

13 files changed

+1801
-100
lines changed

go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ require (
1010
github.com/godbus/dbus/v5 v5.1.0
1111
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b
1212
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e // indirect
13+
github.com/kylelemons/godebug v1.1.0
1314
github.com/openconfig/gnmi v0.0.0-20200617225440-d2b4e6a45802
1415
github.com/openconfig/goyang v0.0.0-20200309174518-a00bece872fc
1516
github.com/openconfig/ygot v0.7.1

translib/acl_app.go

Lines changed: 145 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import (
2828

2929
"github.com/Azure/sonic-mgmt-common/translib/db"
3030
"github.com/Azure/sonic-mgmt-common/translib/ocbinds"
31+
"github.com/Azure/sonic-mgmt-common/translib/path"
3132
"github.com/Azure/sonic-mgmt-common/translib/tlerr"
3233

3334
log "github.com/golang/glog"
@@ -1215,6 +1216,7 @@ func convertOCToInternalIPv4(ruleData db.Value, aclName string, ruleIndex uint32
12151216
if rule.Ipv4.Config.DestinationAddress != nil {
12161217
ruleData.Field["DST_IP"] = *rule.Ipv4.Config.DestinationAddress
12171218
}
1219+
ruleData.Field["IP_TYPE"] = "IPV4ANY"
12181220
}
12191221

12201222
func convertOCToInternalIPv6(ruleData db.Value, aclName string, ruleIndex uint32, rule *ocbinds.OpenconfigAcl_Acl_AclSets_AclSet_AclEntries_AclEntry) {
@@ -1246,6 +1248,7 @@ func convertOCToInternalIPv6(ruleData db.Value, aclName string, ruleIndex uint32
12461248
if rule.Ipv6.Config.DestinationFlowLabel != nil {
12471249
ruleData.Field["DST_FLOWLABEL"] = strconv.FormatInt(int64(*rule.Ipv6.Config.DestinationFlowLabel), 10)
12481250
}
1251+
ruleData.Field["IP_TYPE"] = "IPV6ANY"
12491252
}
12501253

12511254
func convertOCToInternalTransport(ruleData db.Value, aclName string, ruleIndex uint32, rule *ocbinds.OpenconfigAcl_Acl_AclSets_AclSet_AclEntries_AclEntry) {
@@ -1620,6 +1623,19 @@ func getAclTypeOCEnumFromName(val string) (ocbinds.E_OpenconfigAcl_ACL_TYPE, err
16201623
}
16211624
}
16221625

1626+
func convertSonicAclTypeToOC(aclType string) (ocbinds.E_OpenconfigAcl_ACL_TYPE, string) {
1627+
switch aclType {
1628+
case SONIC_ACL_TYPE_IPV4:
1629+
return ocbinds.OpenconfigAcl_ACL_TYPE_ACL_IPV4, "ACL_IPV4"
1630+
case SONIC_ACL_TYPE_IPV6:
1631+
return ocbinds.OpenconfigAcl_ACL_TYPE_ACL_IPV6, "ACL_IPV6"
1632+
case SONIC_ACL_TYPE_L2:
1633+
return ocbinds.OpenconfigAcl_ACL_TYPE_ACL_L2, "ACL_L2"
1634+
default:
1635+
return ocbinds.OpenconfigAcl_ACL_TYPE_UNSET, ""
1636+
}
1637+
}
1638+
16231639
func getAclKeyStrFromOCKey(aclname string, acltype ocbinds.E_OpenconfigAcl_ACL_TYPE) string {
16241640
aclN := strings.Replace(strings.Replace(aclname, " ", "_", -1), "-", "_", -1)
16251641
aclT := acltype.ΛMap()["E_OpenconfigAcl_ACL_TYPE"][int64(acltype)].Name
@@ -1636,9 +1652,136 @@ func isSubtreeRequest(targetUriPath string, nodePath string) bool {
16361652
}
16371653

16381654
func (app *AclApp) translateSubscribe(req translateSubRequest) (translateSubResponse, error) {
1639-
return emptySubscribeResponse(req.path)
1655+
ymap := yangMapTree{
1656+
subtree: map[string]*yangMapTree{
1657+
"acl-sets/acl-set": {
1658+
mapFunc: app.translateSubscribeAclSet,
1659+
subtree: map[string]*yangMapTree{
1660+
"acl-entries/acl-entry": {
1661+
mapFunc: app.translateSubscribeAclEntry,
1662+
},
1663+
},
1664+
},
1665+
"interfaces": {
1666+
mapFunc: app.translateSubscribeAclBindings,
1667+
},
1668+
}}
1669+
1670+
nb := notificationInfoBuilder{
1671+
pathInfo: NewPathInfo(req.path),
1672+
yangMap: ymap,
1673+
}
1674+
return nb.Build()
1675+
}
1676+
1677+
func (app *AclApp) translateSubscribeAclSet(nb *notificationInfoBuilder) error {
1678+
aclName := nb.pathInfo.StringVar("name", "*")
1679+
aclType := nb.pathInfo.StringVar("type", "*")
1680+
1681+
nb.New().PathKey("name", aclName).PathKey("type", aclType)
1682+
nb.Table(db.ConfigDB, ACL_TABLE).Key(aclName + "_" + aclType)
1683+
if nb.SetFieldPrefix("config") {
1684+
nb.Field("description", ACL_DESCRIPTION)
1685+
}
1686+
if nb.SetFieldPrefix("state") {
1687+
nb.Field("description", ACL_DESCRIPTION)
1688+
}
1689+
1690+
return nil
1691+
}
1692+
1693+
func (app *AclApp) translateSubscribeAclEntry(nb *notificationInfoBuilder) error {
1694+
aclName := nb.pathInfo.StringVar("name", "*")
1695+
aclType := nb.pathInfo.StringVar("type", "*")
1696+
ruleSeq := nb.pathInfo.StringVar("sequence-id", "*")
1697+
1698+
nb.New().PathKey("sequence-id", ruleSeq)
1699+
nb.Table(db.ConfigDB, RULE_TABLE).Key(aclName+"_"+aclType, "RULE_"+ruleSeq)
1700+
1701+
ipAclFieldSetter := func(prefix string) {
1702+
if nb.SetFieldPrefix(prefix) {
1703+
nb.Field("source-address", "SRC_IP")
1704+
nb.Field("destination-address", "DST_IP")
1705+
nb.Field("dscp", "DSCP")
1706+
nb.Field("protocol", "IP_PROTOCOL")
1707+
}
1708+
}
1709+
ipv6AclFieldSetter := func(prefix string) {
1710+
if nb.SetFieldPrefix(prefix) {
1711+
nb.Field("source-address", "SRC_IPV6")
1712+
nb.Field("destination-address", "DST_IPV6")
1713+
nb.Field("dscp", "DSCP")
1714+
nb.Field("protocol", "IP_PROTOCOL")
1715+
}
1716+
}
1717+
ipTransportFieldSetter := func(prefix string) {
1718+
if nb.SetFieldPrefix(prefix) {
1719+
nb.Field("source-port", "L4_SRC_PORT")
1720+
nb.Field("source-port", "L4_SRC_PORT_RANGE")
1721+
nb.Field("destination-port", "L4_DST_PORT")
1722+
nb.Field("destination-port", "L4_DST_PORT_RANGE")
1723+
nb.Field("tcp-flags", "TCP_FLAGS")
1724+
}
1725+
}
1726+
if wildcardMatch(aclType, "ACL_IPV4") {
1727+
ipAclFieldSetter("ipv4/config")
1728+
ipAclFieldSetter("ipv4/state")
1729+
ipTransportFieldSetter("transport/config")
1730+
ipTransportFieldSetter("transport/state")
1731+
}
1732+
if wildcardMatch(aclType, "ACL_IPV6") {
1733+
ipv6AclFieldSetter("ipv6/config")
1734+
ipv6AclFieldSetter("ipv6/state")
1735+
ipTransportFieldSetter("transport/config")
1736+
ipTransportFieldSetter("transport/state")
1737+
}
1738+
if nb.SetFieldPrefix("actions/config") {
1739+
nb.Field("forwarding-action", "PACKET_ACTION")
1740+
}
1741+
if nb.SetFieldPrefix("actions/state") {
1742+
nb.Field("forwarding-action", "PACKET_ACTION")
1743+
}
1744+
1745+
return nil
1746+
}
1747+
1748+
func (app *AclApp) translateSubscribeAclBindings(nb *notificationInfoBuilder) error {
1749+
nb.New().OnChange(false).Preferred(Sample)
1750+
return nil
16401751
}
16411752

16421753
func (app *AclApp) processSubscribe(req processSubRequest) (processSubResponse, error) {
1643-
return processSubResponse{}, tlerr.New("not implemented")
1754+
resp := processSubResponse{
1755+
path: req.path,
1756+
}
1757+
1758+
switch req.table.Name {
1759+
case ACL_TABLE:
1760+
if path.GetElemAt(resp.path, 2) != "acl-set" {
1761+
return resp, tlerr.New("Unknown path template: %v", path.String(req.path))
1762+
}
1763+
1764+
_, aclTypeStr := convertSonicAclTypeToOC(req.entry.Get(ACL_TYPE))
1765+
aclName := strings.TrimSuffix(req.key.Get(0), "_"+aclTypeStr)
1766+
path.SetKeyAt(resp.path, 2, "name", aclName)
1767+
path.SetKeyAt(resp.path, 2, "type", aclTypeStr)
1768+
1769+
case RULE_TABLE:
1770+
aclName := req.key.Get(0)
1771+
aclEntry, err := req.dbs[db.ConfigDB].GetEntry(&db.TableSpec{Name: ACL_TABLE}, asKey(aclName))
1772+
if err != nil {
1773+
return resp, err
1774+
}
1775+
1776+
_, aclTypeStr := convertSonicAclTypeToOC(aclEntry.Get(ACL_TYPE))
1777+
aclName = strings.TrimSuffix(aclName, "_"+aclTypeStr)
1778+
path.SetKeyAt(resp.path, 2, "name", aclName)
1779+
path.SetKeyAt(resp.path, 2, "type", aclTypeStr)
1780+
path.SetKeyAt(resp.path, 4, "sequence-id", strings.TrimPrefix(req.key.Get(1), "RULE_"))
1781+
1782+
default:
1783+
return resp, tlerr.New("Unknown table: %s", req.table.Name)
1784+
}
1785+
1786+
return resp, nil
16441787
}

0 commit comments

Comments
 (0)