Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[vppd] Implemented addPolicyRule #6

Open
wants to merge 9 commits into
base: govpp-pantheon-dev2
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
239 changes: 138 additions & 101 deletions drivers/vppd/vppdriver.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,17 +20,18 @@ import (
"fmt"
"hash/fnv"
"os"
"strconv"
"sync"
"time"

"github.com/contiv/netplugin/core"
"github.com/contiv/netplugin/drivers"
"github.com/contiv/netplugin/netmaster/mastercfg"
"github.com/contiv/ofnet"

agent_core "github.com/ligato/cn-infra/core"
"github.com/ligato/cn-infra/logging"
log "github.com/ligato/cn-infra/logging/logrus"

agent_core "github.com/ligato/cn-infra/core"
"github.com/ligato/vpp-agent/clientv1/linux/localclient"
"github.com/ligato/vpp-agent/flavours/linuxlocal"
vpp_acl "github.com/ligato/vpp-agent/plugins/defaultplugins/aclplugin/model/acl"
Expand Down Expand Up @@ -67,7 +68,7 @@ type VppDriverOperState struct {
localNetConfigMutex sync.Mutex
LocalEpConfig map[string]EndpointConfig // Endpoint ID -> Endpoint config
localEpConfigMutex sync.Mutex
LocalACLConfig map[string]ACLConfig // ACL ID -> ACL config
LocalACLConfig map[int][]*ofnet.OfnetPolicyRule // ACL ID -> ACL config
localACLConfigMutex sync.Mutex
}

Expand Down Expand Up @@ -129,7 +130,7 @@ func (d *VppDriver) Init(info *core.InstanceInfo) error {

d.oper.LocalNetConfig = make(map[string]NetworkConfig)
d.oper.LocalEpConfig = make(map[string]EndpointConfig)
d.oper.LocalACLConfig = make(map[string]ACLConfig)
d.oper.LocalACLConfig = make(map[int][]*ofnet.OfnetPolicyRule)

// write the oper
err = d.oper.Write()
Expand All @@ -154,7 +155,7 @@ func (d *VppDriver) Init(info *core.InstanceInfo) error {

// make sure LocalACLConfig exist
if d.oper.LocalACLConfig == nil {
d.oper.LocalACLConfig = make(map[string]ACLConfig)
d.oper.LocalACLConfig = make(map[int][]*ofnet.OfnetPolicyRule)
rewriteOper = true
}

Expand Down Expand Up @@ -368,11 +369,28 @@ func (d *VppDriver) CreateEndpoint(id string) error {
VppInterface(epcfg.afpacket).
Send().
ReceiveReply()

if err != nil {
netcfg.bd.Interfaces = origBfIfs
log.Errorf("Failed to create endpoint id='%s', Err: %v", id, err)
return err
}

// Apply policy if any at the endpoint
d.oper.localACLConfigMutex.Lock()
defer d.oper.localACLConfigMutex.Unlock()
rule, epPolicyCfgExists := d.oper.LocalACLConfig[cfgEp.EndpointGroupID]
if !epPolicyCfgExists {
log.Infof("No policy currently applied to the interface")
} else {
// Add policy to endpoint if exists
err = addEndpointACL(rule, cfgEp.EndpointGroupID, afPacketName)
if err != nil {
log.Errorf("Failed to create endpoint id='%s', Err: %v", id, err)
return err
}
}

// Store the endpoint configuration
d.oper.localEpConfigMutex.Lock()
defer d.oper.localEpConfigMutex.Unlock()
Expand Down Expand Up @@ -402,6 +420,7 @@ func (d *VppDriver) CreateEndpoint(id string) error {
operEp.Clear()
}
}()

return nil
}

Expand Down Expand Up @@ -616,109 +635,20 @@ func (d *VppDriver) AddPolicyRule(id string) error {
return err
}

d.oper.localACLConfigMutex.Lock()
defer d.oper.localACLConfigMutex.Unlock()
_, exists := d.oper.LocalACLConfig[id]
if exists {
err = fmt.Errorf("ACL id='%s' is already configured", id)
log.Error(err.Error())
return err
}

log.Infof("EPGID = %d", ruleCfg.EndpointGroupID)
epgID := ruleCfg.EndpointGroupID
vppRule := &ruleCfg.OfnetPolicyRule
log.Infof("Add policy rule with id='%s' and config: %+v", id, vppRule)

aclcfg := ACLConfig{}
var action *vpp_acl.AccessLists_Acl_Rule_Actions
var matches *vpp_acl.AccessLists_Acl_Rule_Matches

// Action rule to be VPP specific
if vppRule.Action == "allow" {
action = &vpp_acl.AccessLists_Acl_Rule_Actions{
AclAction: vpp_acl.AclAction_PERMIT,
}
} else if vppRule.Action == "deny" {
action = &vpp_acl.AccessLists_Acl_Rule_Actions{
AclAction: vpp_acl.AclAction_DENY,
}
}

// Src/DstNetwork choice based on protocol
if vppRule.IpProtocol == 6 {
matches = &vpp_acl.AccessLists_Acl_Rule_Matches{
IpRule: &vpp_acl.AccessLists_Acl_Rule_Matches_IpRule{
Ip: &vpp_acl.AccessLists_Acl_Rule_Matches_IpRule_Ip{
DestinationNetwork: vppRule.DstIpAddr,
SourceNetwork: vppRule.SrcIpAddr,
},
Tcp: &vpp_acl.AccessLists_Acl_Rule_Matches_IpRule_Tcp{
DestinationPortRange: &vpp_acl.AccessLists_Acl_Rule_Matches_IpRule_Tcp_DestinationPortRange{
LowerPort: uint32(vppRule.DstPort),
UpperPort: uint32(vppRule.DstPort),
},
SourcePortRange: &vpp_acl.AccessLists_Acl_Rule_Matches_IpRule_Tcp_SourcePortRange{
LowerPort: uint32(vppRule.SrcPort),
UpperPort: uint32(vppRule.SrcPort),
},
},
},
}
} else if vppRule.IpProtocol == 17 {
matches = &vpp_acl.AccessLists_Acl_Rule_Matches{
IpRule: &vpp_acl.AccessLists_Acl_Rule_Matches_IpRule{
Ip: &vpp_acl.AccessLists_Acl_Rule_Matches_IpRule_Ip{
DestinationNetwork: vppRule.DstIpAddr,
SourceNetwork: vppRule.SrcIpAddr,
},
Udp: &vpp_acl.AccessLists_Acl_Rule_Matches_IpRule_Udp{
DestinationPortRange: &vpp_acl.AccessLists_Acl_Rule_Matches_IpRule_Udp_DestinationPortRange{
LowerPort: uint32(vppRule.DstPort),
UpperPort: uint32(vppRule.DstPort),
},
SourcePortRange: &vpp_acl.AccessLists_Acl_Rule_Matches_IpRule_Udp_SourcePortRange{
LowerPort: uint32(vppRule.SrcPort),
UpperPort: uint32(vppRule.SrcPort),
},
},
},
}
} else {
matches = &vpp_acl.AccessLists_Acl_Rule_Matches{
IpRule: &vpp_acl.AccessLists_Acl_Rule_Matches_IpRule{
Ip: &vpp_acl.AccessLists_Acl_Rule_Matches_IpRule_Ip{
DestinationNetwork: vppRule.DstIpAddr,
SourceNetwork: vppRule.SrcIpAddr,
},
},
}
}

aclcfg.acl = &vpp_acl.AccessLists_Acl{
AclName: "acl-" + id,
Rules: []*vpp_acl.AccessLists_Acl_Rule{
{
RuleName: vppRule.RuleId,
Actions: action,
Matches: matches,
},
},
}

log.Info("ACL config: ", aclcfg)

err = localclient.DataChangeRequest(vppDriverID).
Put().
ACL(aclcfg.acl).
Send().
ReceiveReply()

// save local endpoint info
d.oper.localACLConfigMutex.Lock()
d.oper.LocalACLConfig[epgID] = append(d.oper.LocalACLConfig[epgID], vppRule)
d.oper.localACLConfigMutex.Unlock()
err = d.oper.Write()
if err != nil {
log.Errorf("Failed to create policy rule id='%s', Err: %v", id, err)
return err
}

// Store the network configuration
d.oper.LocalACLConfig[id] = aclcfg
return nil
}

Expand Down Expand Up @@ -751,3 +681,110 @@ func genNetworkVNI(netID string) uint32 {
}
return vni
}

func addEndpointACL(rule []*ofnet.OfnetPolicyRule, epGroupID int, afPacketName string) error {
aclcfg := ACLConfig{}
var action *vpp_acl.AccessLists_Acl_Rule_Actions
var matches *vpp_acl.AccessLists_Acl_Rule_Matches
var interfaces *vpp_acl.AccessLists_Acl_Interfaces

for id, vppRule := range rule {
ruleID := vppRule.RuleId
epPolicyIf := []string{afPacketName}

if ruleID[len(ruleID)-2:] == "Rx" {
interfaces = &vpp_acl.AccessLists_Acl_Interfaces{
Egress: epPolicyIf,
}
} else {
interfaces = &vpp_acl.AccessLists_Acl_Interfaces{
Ingress: epPolicyIf,
}
}

// Action rule to be VPP specific
if vppRule.Action == "allow" {
action = &vpp_acl.AccessLists_Acl_Rule_Actions{
AclAction: vpp_acl.AclAction_PERMIT,
}
} else if vppRule.Action == "deny" {
action = &vpp_acl.AccessLists_Acl_Rule_Actions{
AclAction: vpp_acl.AclAction_DENY,
}
}

// Src/DstNetwork choice based on protocol
if vppRule.IpProtocol == 6 {
matches = &vpp_acl.AccessLists_Acl_Rule_Matches{
IpRule: &vpp_acl.AccessLists_Acl_Rule_Matches_IpRule{
Ip: &vpp_acl.AccessLists_Acl_Rule_Matches_IpRule_Ip{
DestinationNetwork: vppRule.DstIpAddr,
SourceNetwork: vppRule.SrcIpAddr,
},
Tcp: &vpp_acl.AccessLists_Acl_Rule_Matches_IpRule_Tcp{
DestinationPortRange: &vpp_acl.AccessLists_Acl_Rule_Matches_IpRule_Tcp_DestinationPortRange{
LowerPort: uint32(vppRule.DstPort),
UpperPort: uint32(vppRule.DstPort),
},
SourcePortRange: &vpp_acl.AccessLists_Acl_Rule_Matches_IpRule_Tcp_SourcePortRange{
LowerPort: uint32(vppRule.SrcPort),
UpperPort: uint32(vppRule.SrcPort),
},
},
},
}
} else if vppRule.IpProtocol == 17 {
matches = &vpp_acl.AccessLists_Acl_Rule_Matches{
IpRule: &vpp_acl.AccessLists_Acl_Rule_Matches_IpRule{
Ip: &vpp_acl.AccessLists_Acl_Rule_Matches_IpRule_Ip{
DestinationNetwork: vppRule.DstIpAddr,
SourceNetwork: vppRule.SrcIpAddr,
},
Udp: &vpp_acl.AccessLists_Acl_Rule_Matches_IpRule_Udp{
DestinationPortRange: &vpp_acl.AccessLists_Acl_Rule_Matches_IpRule_Udp_DestinationPortRange{
LowerPort: uint32(vppRule.DstPort),
UpperPort: uint32(vppRule.DstPort),
},
SourcePortRange: &vpp_acl.AccessLists_Acl_Rule_Matches_IpRule_Udp_SourcePortRange{
LowerPort: uint32(vppRule.SrcPort),
UpperPort: uint32(vppRule.SrcPort),
},
},
},
}
} else {
matches = &vpp_acl.AccessLists_Acl_Rule_Matches{
IpRule: &vpp_acl.AccessLists_Acl_Rule_Matches_IpRule{
Ip: &vpp_acl.AccessLists_Acl_Rule_Matches_IpRule_Ip{
DestinationNetwork: vppRule.DstIpAddr,
SourceNetwork: vppRule.SrcIpAddr,
},
},
}
}

aclcfg.acl = &vpp_acl.AccessLists_Acl{
AclName: "acl-" + vppRule.RuleId[0:7] + "-id-" + strconv.Itoa(id) + afPacketName + "-" + ruleID[len(ruleID)-2:],
Rules: []*vpp_acl.AccessLists_Acl_Rule{
{
RuleName: vppRule.RuleId + strconv.Itoa(id),
Actions: action,
Matches: matches,
},
},
Interfaces: interfaces,
}

err := localclient.DataChangeRequest(vppDriverID).
Put().
ACL(aclcfg.acl).
Send().
ReceiveReply()

if err != nil {
log.Errorf("Failed to create policy rule id='%s', Err: %v", vppRule.RuleId, err)
return err
}
}
return nil
}
4 changes: 3 additions & 1 deletion netmaster/mastercfg/policyRuleState.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ const (
type CfgPolicyRule struct {
core.CommonState
ofnet.OfnetPolicyRule
EndpointGroupID int // Endpoint group where this policy is attached to
}

// Write the state.
Expand Down Expand Up @@ -64,10 +65,11 @@ func (s *CfgPolicyRule) Clear() error {
}

// addPolicyRuleState adds policy rule to state store
func addPolicyRuleState(ofnetRule *ofnet.OfnetPolicyRule) error {
func addPolicyRuleState(ofnetRule *ofnet.OfnetPolicyRule, epgID int) error {
ruleCfg := &CfgPolicyRule{}
ruleCfg.StateDriver = stateStore
ruleCfg.OfnetPolicyRule = (*ofnetRule)
ruleCfg.EndpointGroupID = epgID

// Save the rule
return ruleCfg.Write()
Expand Down
4 changes: 2 additions & 2 deletions netmaster/mastercfg/policyState.go
Original file line number Diff line number Diff line change
Expand Up @@ -294,7 +294,7 @@ func (gp *EpgPolicy) createOfnetRule(rule *contivModel.Rule, dir string) (*ofnet
// }

// Send AddRule to netplugin agents
err = addPolicyRuleState(ofnetRule)
err = addPolicyRuleState(ofnetRule, gp.EndpointGroupID)
if err != nil {
log.Errorf("Error creating rule {%+v}. Err: %v", ofnetRule, err)
return nil, err
Expand Down Expand Up @@ -380,7 +380,7 @@ func (gp *EpgPolicy) DelRule(rule *contivModel.Rule) error {
// }

// Send DelRule to netplugin agents
err = delPolicyRuleState(ofnetRule)
err := delPolicyRuleState(ofnetRule)
if err != nil {
log.Errorf("Error deleting the ofnet rule {%+v}. Err: %v", ofnetRule, err)
}
Expand Down